Esempio n. 1
0
bool DirectiveService::getDirectives(
   BtpAction* action, DynamicObject& in, DynamicObject& out)
{
   bool rval = false;

   UserId userId;
   if(mNode->checkLogin(action, &userId))
   {
      rval = true;

      // turn user ID into a key
      char key[22];
      snprintf(key, 22, "%" PRIu64, userId);

      // return user's directive cache
      mCacheLock.lock();
      {
         if(mDirectives->hasMember(key))
         {
            out = mDirectives[key];
         }
         else
         {
            out->setType(Map);
         }
      }
      mCacheLock.unlock();
   }

   return rval;
}
Esempio n. 2
0
// FIXME: should this be using new JSON-LD frame stuff rather than this?
bool JsonLd::filter(
   DynamicObject& context, DynamicObject& filter,
   DynamicObject& in, DynamicObject& out, bool simplify)
{
   bool rval;
   DynamicObject normFilter;
   DynamicObject normIn;
   DynamicObject normOut;
   normOut->setType(Map);
   // remove contexts
   rval =
      removeContext(filter, normFilter) &&
      removeContext(in, normIn);
   // filter to the output
   if(rval)
   {
      _filter(normFilter, normIn, normOut);
      // FIXME: fixup graph
      // Search normOut for unknown references that are in normIn and add them.
      // Futher optimize by checking reference count and embedding data as
      // needed. This will result in a graph that is as complete as the input
      // with regard to references.

      // flatten in the case of one result
      if(simplify && normOut->hasMember("@") && normOut["@"]->length() == 1)
      {
         normOut = normOut["@"][0];
      }
   }
   // add context to output
   rval = rval && addContext(context, normOut, out);
   return rval;
}
Esempio n. 3
0
/**
 * Gets the field names and values for a particular X509_NAME.
 *
 * For instance, if the subject name is passed, then the "CN" (common name)
 * value, "C" (country) value, etc. will be added to the output.
 *
 * @param name the X509_name, i.e. X509_get_subject_name(mX509).
 * @param output the array to populate.
 */
static void _getX509NameValues(X509_NAME* name, DynamicObject& output)
{
   output->setType(Array);

   unsigned char* value;
   X509_NAME_ENTRY* entry;
   int count = X509_NAME_entry_count(name);
   for(int i = 0; i < count; ++i)
   {
      entry = X509_NAME_get_entry(name, i);

      // get entry name (object) and value (data)
      ASN1_OBJECT* obj = X509_NAME_ENTRY_get_object(entry);
      ASN1_STRING* str = X509_NAME_ENTRY_get_data(entry);

      // convert name and value to strings
      int nid = OBJ_obj2nid(obj);
      const char* sn = OBJ_nid2sn(nid);
      if(ASN1_STRING_to_UTF8(&value, str) != -1)
      {
         DynamicObject& item = output->append();
         item["type"] = sn;
         item["value"] = value;
         OPENSSL_free(value);
      }
   }
}
Esempio n. 4
0
/**
 * Recursively applies context to the given input object.
 *
 * @param ctx the context to use.
 * @param usedCtx the used context values.
 * @param predicate the related predicate or NULL if none.
 * @param in the input object.
 * @param out the contextualized output object.
 */
static void _applyContext(
   DynamicObject& ctx, DynamicObject& usedCtx,
   const char* predicate, DynamicObject& in, DynamicObject& out)
{
   if(in.isNull())
   {
      out.setNull();
   }
   else
   {
      // initialize output
      DynamicObjectType inType = in->getType();
      out->setType(inType);

      if(inType == Map)
      {
         // add context to each property in the map
         char* tmp = NULL;
         DynamicObjectIterator i = in.getIterator();
         while(i->hasNext())
         {
            // compact predicate
            DynamicObject& next = i->next();
            DynamicObject cp(NULL);
            const char* p;
            if(strcmp(i->getName(), "@") == 0)
            {
               p = "@";
            }
            else
            {
               cp = _compactString(ctx, usedCtx, NULL, i->getName(), &tmp);
               p = cp;
            }
            // recurse
            _applyContext(ctx, usedCtx, p, next, out[p]);
         }
         free(tmp);
      }
      else if(inType == Array)
      {
         // apply context to each object in the array
         DynamicObjectIterator i = in.getIterator();
         while(i->hasNext())
         {
            DynamicObject& next = i->next();
            _applyContext(ctx, usedCtx, predicate, next, out->append());
         }
      }
      // only strings need context applied, numbers & booleans don't
      else if(inType == String)
      {
         // compact string
         char* tmp = NULL;
         out = _compactString(ctx, usedCtx, predicate, in->getString(), &tmp);
         free(tmp);
      }
   }
}
Esempio n. 5
0
DynamicObject DynamicObjectImpl::getStats()
{
   DynamicObject rval;
   rval->setType(Map);

#if defined(MO_DYNO_COUNTS) || defined(MO_DYNO_KEY_COUNTS)
   #define MAKESTAT(d, s) \
      MO_STMT_START { \
         d["counts"]["live"] = s.counts.live; \
         d["counts"]["dead"] = s.counts.dead; \
         d["counts"]["max"] = s.counts.max; \
         d["bytes"]["live"] = s.bytes.live; \
         d["bytes"]["dead"] = s.bytes.dead; \
         d["bytes"]["max"] = s.bytes.max; \
      } MO_STMT_END
#endif // defined(MO_DYNO_COUNTS) || defined(MO_DYNO_KEY_COUNTS)

#ifdef MO_DYNO_COUNTS
   #define GETSTAT(s, type) \
      MO_STMT_START { \
         DynamicObject& d = s[MO_STRINGIFY(type)]; \
         MAKESTAT(d, _stats_counts[type]); \
      } MO_STMT_END
   GETSTAT(rval, Object);
   GETSTAT(rval, String);
   GETSTAT(rval, Boolean);
   GETSTAT(rval, Int32);
   GETSTAT(rval, UInt32);
   GETSTAT(rval, Int64);
   GETSTAT(rval, UInt64);
   GETSTAT(rval, Double);
   GETSTAT(rval, Map);
   GETSTAT(rval, Array);
   GETSTAT(rval, Key);
   GETSTAT(rval, StringValue);
   #undef GETSTAT
#endif // MO_DYNO_COUNTS

#ifdef MO_DYNO_KEY_COUNTS
   {
      _stats_key_counts_lock.lock();
      DynamicObject& d = rval["KeyCounts"];
      d["count"] = _stats_key_counts.size();
      d["keys"]->setType(Map);
      _StatsKeyMap::iterator i =
         _stats_key_counts.begin();
      for(; i != _stats_key_counts.end(); ++i)
      {
         // create new stat entry
         DynamicObject& s = d["keys"][i->first];
         MAKESTAT(s, _stats_key_counts[i->first]);
      }
      _stats_key_counts_lock.unlock();
   }
#endif // MO_DYNO_KEY_COUNTS

   return rval;
}
Esempio n. 6
0
DynamicObject& Exception::getDetails()
{
   if(mDetails->isNull())
   {
      DynamicObject details;
      details->setType(Map);
      *mDetails = details;
   }

   return *mDetails;
}
Esempio n. 7
0
/**
 * Recursively removes context from the given input object.
 *
 * @param ctx the context to use (changes during recursion as necessary).
 * @param in the input object.
 * @param out the normalized output object.
 * @param bnodeId the last blank node ID used.
 *
 * @return true on success, false on failure with exception set.
 */
static bool _removeContext(
   DynamicObject& ctx, DynamicObject& in, DynamicObject& out, int& bnodeId)
{
   bool rval = true;

   if(in.isNull())
   {
      out.setNull();
   }
   else
   {
      // initialize output
      DynamicObjectType inType = in->getType();
      out->setType(inType);

      // update context
      if(inType == Map && in->hasMember("#"))
      {
         ctx = in["#"];
      }

      if(inType == Map)
      {
         rval = _normalize(ctx, in, NULL, &out, bnodeId);
      }
      else if(inType == Array)
      {
         // strip context from each object in the array
         DynamicObjectIterator i = in.getIterator();
         while(i->hasNext())
         {
            DynamicObject& next = i->next();
            rval = _removeContext(ctx, next, out->append(), bnodeId);
         }
      }
   }

   return rval;
}
Esempio n. 8
0
static void runConfigManagerTest(TestRunner& tr)
{
   tr.group("ConfigManager");

   tr.test("init");
   {
      DynamicObject expect;
      expect->setType(Map);
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]->setType(Map);
      assert(cm.addConfig(cfg));
      assertDynoCmp(cm.getConfig("config", true), cfg);
      assertDynoCmp(cm.getConfig("config", false), expect);
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("init & clear");
   {
      DynamicObject expect;
      expect->setType(Map);
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]->setType(Map);
      assert(cm.addConfig(cfg));
      cm.clear();
      Config cfg2 = cm.getConfig("config");
      assert(cfg2.isNull());
   }
   tr.passIfException();

   tr.test("1 config");
   {
      DynamicObject expect;
      expect->setType(Map);
      expect["a"] = 0;
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]["a"] = 0;
      assert(cm.addConfig(cfg));
      assertNoExceptionSet();
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("config change");
   {
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]["a"] = 0;
      assert(cm.addConfig(cfg));
      DynamicObject a;
      a["a"] = 0;
      assertDynoCmp(cm.getConfig("config"), a);
      Config change = cm.getConfig("config", true);
      change[ConfigManager::MERGE]["a"] = 1;
      assert(cm.setConfig(change));
      DynamicObject expect;
      expect["a"] = 1;
      assert(cm.getConfig("config") != a);
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("invalid set config");
   {
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]["a"] = 0;
      assert(!cm.setConfig(cfg));
   }
   tr.passIfException();

   tr.test("double add config");
   {
      ConfigManager cm;
      Config cfg;
      cfg[ConfigManager::ID] = "config";
      cfg[ConfigManager::MERGE]["a"] = 0;
      assert(cm.addConfig(cfg));
      cfg[ConfigManager::MERGE]["a"] = 1;
      assert(cm.addConfig(cfg));
      DynamicObject expect;
      expect["a"] = 1;
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("add");
   {
      DynamicObject expect;
      expect["a"] = 0;
      expect["b"] = 1;
      expect["c"] = 2;
      ConfigManager cm;
      Config a;
      a[ConfigManager::ID] = "config";
      a[ConfigManager::MERGE]["a"] = 0;
      Config b;
      b[ConfigManager::ID] = "config";
      b[ConfigManager::MERGE]["b"] = 1;
      Config c;
      c[ConfigManager::ID] = "config";
      c[ConfigManager::MERGE]["c"] = 2;
      assert(cm.addConfig(a));
      assertNoExceptionSet();
      assert(cm.addConfig(b));
      assertNoExceptionSet();
      assert(cm.addConfig(c));
      assertNoExceptionSet();
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("bad remove");
   {
      ConfigManager cm;
      assert(!cm.removeConfig("error"));
      assertExceptionSet();
      Exception::clear();
   }
   tr.passIfNoException();

   tr.test("remove");
   {
      DynamicObject expect;
      expect["a"] = 0;
      expect["b"] = 1;
      expect["c"] = 2;
      ConfigManager cm;
      Config a;
      a[ConfigManager::ID] = "config a";
      a[ConfigManager::GROUP] = "group";
      a[ConfigManager::MERGE]["a"] = 0;
      Config b;
      b[ConfigManager::ID] = "config b";
      b[ConfigManager::GROUP] = "group";
      b[ConfigManager::MERGE]["b"] = 1;
      Config c;
      c[ConfigManager::ID] = "config c";
      c[ConfigManager::GROUP] = "group";
      c[ConfigManager::MERGE]["c"] = 2;
      assert(cm.addConfig(a));
      assertNoExceptionSet();
      assert(cm.addConfig(b));
      assertNoExceptionSet();
      assert(cm.addConfig(c));
      assertNoExceptionSet();
      assertDynoCmp(cm.getConfig("group"), expect);
      DynamicObject expect2;
      expect2["a"] = 0;
      expect2["c"] = 2;
      assert(cm.removeConfig("config b"));
      assertDynoCmp(cm.getConfig("group"), expect2);
   }
   tr.passIfNoException();

   tr.test("default value");
   {
      ConfigManager cm;
      Config a;
      a[ConfigManager::ID] = "config a";
      a[ConfigManager::MERGE] = 1;
      assert(cm.addConfig(a));
      assertNoExceptionSet();
      Config b;
      b[ConfigManager::ID] = "config b";
      b[ConfigManager::PARENT] = "config a";
      b[ConfigManager::MERGE] = ConfigManager::DEFAULT_VALUE;
      assert(cm.addConfig(b));
      assertNoExceptionSet();
      DynamicObject expect;
      expect = 1;
      assertDynoCmp(cm.getConfig("config b"), expect);
   }
   tr.passIfNoException();

   tr.test("default values");
   {
      ConfigManager cm;
      Config cfga;
      cfga[ConfigManager::ID] = "config a";
      Config& a = cfga[ConfigManager::MERGE];
      a[0] = 10;
      a[1] = 11;
      a[2]["0"] = 120;
      a[2]["1"] = 121;
      assert(cm.addConfig(cfga));
      assertNoExceptionSet();
      Config cfgb;
      cfgb[ConfigManager::ID] = "config b";
      cfgb[ConfigManager::PARENT] = "config a";
      Config& b = cfgb[ConfigManager::MERGE];
      b[0] = ConfigManager::DEFAULT_VALUE;
      b[1] = 21;
      b[2]["0"] = ConfigManager::DEFAULT_VALUE;
      b[2]["1"] = 221;
      assert(cm.addConfig(cfgb));
      assertNoExceptionSet();
      DynamicObject expect;
      expect[0] = 10;
      expect[1] = 21;
      expect[2]["0"] = 120;
      expect[2]["1"] = 221;
      assertDynoCmp(cm.getConfig("config b"), expect);
   }
   tr.passIfNoException();


   tr.test("keyword substitution {RESOURCE_DIR}");
   {
      DynamicObject expect;
      expect["dir"] = "/the/real/dir";
      expect["dir-plus"] = "/the/real/dir/plus/more";
      //expect["name"] = "Digital Bazaar, Inc.";
      ConfigManager cm;
      Config a;
      a[ConfigManager::ID] = "config";
      a[ConfigManager::MERGE]["dir"] = "{RESOURCE_DIR}";
      a[ConfigManager::MERGE]["dir-plus"] = "{RESOURCE_DIR}/plus/more";
      // FIXME: only supports "{RESOURCE_DIR}" now
      //a[ConfigManager::MERGE]["other"] = "{DB}";
      cm.setKeyword("RESOURCE_DIR", "/the/real/dir");
      //cm.setKeyword("DB", "Digital Bazaar, Inc.");
      assert(cm.addConfig(a));
      assertNoExceptionSet();
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("keyword substitution {CURRENT_DIR}");
   {
      DynamicObject expect;
      string cwd;
      string cwdPlusMore;
      string absoluteDir;
      File configFile = File::createTempFile("test-config-file");
      FileOutputStream fos(configFile);

      // create and populate the config file
      string configFileText =
         "{\n"
         "\"_id_\": \"config\",\n"
         "\"_merge_\": {\n"
         "   \"dir\": \"{CURRENT_DIR}\",\n"
         "   \"dir-plus\": \"{CURRENT_DIR}/plus/more\" }\n"
         "}\n";
      fos.write(configFileText.c_str(), configFileText.length());
      fos.close();

      // modify the current working directory to the expected value
      absoluteDir = File::dirname(configFile->getAbsolutePath());
      cwd = absoluteDir.c_str();
      cwdPlusMore = cwd.c_str();
      cwdPlusMore.append("/plus/more");

      // set the expected values
      expect["dir"] = cwd.c_str();
      expect["dir-plus"] = cwdPlusMore.c_str();

      // create the configuration
      ConfigManager cm;
      assert(cm.addConfigFile(configFile->getAbsolutePath(),
         true, absoluteDir.c_str(), true, false));
      assertNoExceptionSet();
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

#if 0
   tr.test("user preferences");
   {
      ConfigManager cm;

      // node
      // built in or loaded defaults
      DynamicObject nodec;
      nodec["node"]["host"] = "localhost";
      nodec["node"]["port"] = 19100;
      nodec["node"]["modulePath"]->append("/usr/lib/bitmunk/modules");
      nodec["node"]["userModulePath"] = "~/.bitmunk/modules";
      assert(cm.addConfig(nodec));
      assertNoExceptionSet();

      // user
      // loaded defaults
      DynamicObject userc;
      userc["node"]["port"] = 19100;
      userc["node"]["comment"] = "My precious...";
      assert(cm.addConfig(userc, ConfigManager::Custom));
      assertNoExceptionSet();

      // user makes changes during runtime
      DynamicObject c = cm.getConfig();
      c["node"]["port"] = 19200;
      c["node"]["userModulePath"] = "~/.bitmunk/modules:~/.bitmunk/modules-dev";
      c["node"][ConfigManager::TMP]["not in changes"] = true;

      // get the changes from defaults to current config
      // serialize this to disk as needed
      DynamicObject changes;
      cm.getChanges(changes);

      // check it's correct
      DynamicObject expect;
      expect["node"]["port"] = 19200;
      expect["node"]["comment"] = "My precious...";
      expect["node"]["userModulePath"] = "~/.bitmunk/modules:~/.bitmunk/modules-dev";
      // NOTE: will not have TMP var
      assertDynoCmp(changes, expect);
   }
   tr.passIfNoException();
#endif

   tr.test("versioning");
   {
      ConfigManager cm;

      cm.getVersions()->clear();
      Config c;
      c[ConfigManager::ID] = "config";
      assert(cm.addConfig(c));
      assertNoExceptionSet();

      // config has no version - no check done - pass
      cm.addVersion("1");
      assert(cm.addConfig(c));
      assertNoExceptionSet();

      // config has known version - pass
      c[ConfigManager::VERSION] = "1";
      assert(cm.addConfig(c));
      assertNoExceptionSet();
      assert(cm.removeConfig("config"));

      // config has unknown version - fail
      c[ConfigManager::VERSION] = "2";
      assert(!cm.addConfig(c));
      assertExceptionSet();
      Exception::clear();
   }
   tr.passIfNoException();

   tr.test("empty array & map");
   {
      ConfigManager cm;
      DynamicObject a;
      a[ConfigManager::ID] = "config";
      a[ConfigManager::MERGE][0]->setType(Array);
      a[ConfigManager::MERGE][1]->setType(Map);
      assert(cm.addConfig(a));
      assertNoExceptionSet();
      DynamicObject expect;
      expect[0]->setType(Array);
      expect[1]->setType(Map);
      assertDynoCmp(cm.getConfig("config"), expect);
   }
   tr.passIfNoException();

   tr.test("empty group ids");
   {
      ConfigManager cm;
      DynamicObject expect;
      expect->setType(Array);
      assertDynoCmp(cm.getIdsInGroup("Not-A-Group"), expect);
   }
   tr.passIfNoException();

   tr.test("group ids");
   {
      ConfigManager cm;
      DynamicObject c;

      c[ConfigManager::ID] = "c0";
      c[ConfigManager::GROUP] = "c";
      assert(cm.addConfig(c));
      assertNoExceptionSet();

      c[ConfigManager::ID] = "c1";
      c[ConfigManager::GROUP] = "c";
      assert(cm.addConfig(c));
      assertNoExceptionSet();

      DynamicObject expect;
      expect->setType(Array);
      expect[0] = "c0";
      expect[1] = "c1";
      assertDynoCmp(cm.getIdsInGroup("c"), expect);
   }
   tr.passIfNoException();

   tr.test("replace keywords");
   {
      ConfigManager cm;
      DynamicObject c;

      c[ConfigManager::ID] = "c";
      c[ConfigManager::MERGE]["test"] = "{A}";
      DynamicObject vars;
      vars["A"] = "a";
      assertNoException(ConfigManager::replaceKeywords(c, vars));

      DynamicObject expect;
      expect[ConfigManager::ID] = "c";
      expect[ConfigManager::MERGE]["test"] = "a";
      assertDynoCmp(c, expect);
   }
   tr.passIfNoException();

   tr.test("replace keywords (invalid keyword)");
   {
      ConfigManager cm;
      DynamicObject c;

      c[ConfigManager::ID] = "c";
      c[ConfigManager::MERGE]["test"] = "{UNKNOWN}";
      DynamicObject vars;
      vars["A"] = "a";
      assertException(ConfigManager::replaceKeywords(c, vars));
   }
   tr.passIfException();

   tr.ungroup();
}
static void runNodeMonitorTest(TestRunner& tr)
{
   tr.group("NodeMonitor");

   tr.test("empty");
   {
      NodeMonitor nm;
      DynamicObject expect;
      expect->setType(Map);
      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("add1 init");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["init"] = "foo";
      r = nm.addState("s", si);
      assert(r);

      DynamicObject expect;
      expect["s"] = "foo";

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("addN init");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["s"]["init"] = "foo";
      si["u"]["init"] = (uint64_t)0;
      si["i"]["init"] = (int64_t)0;
      si["d"]["init"] = 0.;
      r = nm.addStates(si);
      assert(r);

      DynamicObject expect;
      expect["s"] = "foo";
      expect["u"] = (uint64_t)0;
      expect["i"] = (int64_t)0;
      expect["d"] = 0.;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("remove");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["n"]["init"] = (uint64_t)0;
      si["rem"]["init"] = (uint64_t)0;
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["rem"].setNull();
      r = nm.removeStates(s);
      assert(r);

      DynamicObject expect;
      expect["n"] = (uint64_t)0;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("set");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["n"]["init"] = (uint64_t)0;
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["n"] = (uint64_t)123;
      r = nm.setStates(s);
      assert(r);

      DynamicObject expect;
      expect["n"] = (uint64_t)123;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("adj");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["n"]["init"] = (uint64_t)0;
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["n"] = (uint64_t)1;
      r = nm.adjustStates(s);
      assert(r);
      r = nm.adjustStates(s);
      assert(r);
      r = nm.adjustStates(s);
      assert(r);

      DynamicObject expect;
      expect["n"] = (uint64_t)3;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("reset");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["n"]["init"] = (uint64_t)100;
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["n"] = (uint64_t)123;
      r = nm.setStates(s);
      assert(r);
      r = nm.resetStates(s);
      assert(r);

      DynamicObject expect;
      expect["n"] = (uint64_t)100;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("adj neg");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["n"]["init"] = (uint64_t)100;
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["n"] = (int64_t)-1;
      r = nm.adjustStates(s);
      assert(r);

      DynamicObject expect;
      expect["n"] = (uint64_t)99;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("getN");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject si;
      si["a"]["init"] = "a";
      si["b"]["init"] = "b";
      si["c"]["init"] = "c";
      r = nm.addStates(si);
      assert(r);

      DynamicObject s;
      s["b"].setNull();
      s["c"].setNull();
      r = nm.getStates(s);
      assert(r);

      DynamicObject expect;
      expect["b"] = "b";
      expect["c"] = "c";

      assertDynoCmp(expect, s);
   }
   tr.passIfNoException();

   tr.test("add ex");
   {
      NodeMonitor nm;
      DynamicObject si;
      si["bad"] = 0;
      assertException(nm.addStates(si));
      Exception::clear();
   }
   tr.passIfNoException();

   tr.test("rem ex");
   {
      NodeMonitor nm;
      DynamicObject s;
      s["a"] = 0;
      assertException(nm.removeStates(s));
      Exception::clear();
   }
   tr.passIfNoException();

   // Not for use with async StateMonitor implementation.
   /*
   tr.test("set ex");
   {
      bool r;
      NodeMonitor nm;
      DynamicObject s;
      s["a"] = 0;
      assertException(nm.setStates(s));
      Exception::clear();
   }
   tr.passIfNoException();
   */

   tr.test("get ex");
   {
      NodeMonitor nm;
      DynamicObject s;
      s["a"] = 0;
      assertException(nm.getStates(s));
      Exception::clear();
   }
   tr.passIfNoException();

   tr.test("adj ex");
   {
      NodeMonitor nm;
      DynamicObject s;
      s["a"] = 1;
      assertException(nm.adjustStates(s));
      Exception::clear();
   }
   tr.passIfNoException();

   tr.test("adj type ex");
   {
      NodeMonitor nm;
      DynamicObject si;
      si["a"]["init"] = (uint64_t)0;
      assertNoException(
         nm.addStates(si));

      // Not for use with async StateMonitor implementation.
      /*
      DynamicObject s;
      s["a"] = 0.;
      assertException(nm.adjustStates(s));
      Exception::clear();
      */
   }
   tr.passIfNoException();

   tr.test("txn adj ex");
   {
      // check bad transaction doesn't change values
      NodeMonitor nm;
      DynamicObject si;
      si["a"]["init"] = (uint64_t)10;
      si["b"]["init"] = (uint64_t)10;
      assertNoException(
         nm.addStates(si));

      // Not for use with async StateMonitor implementation.
      /*
      DynamicObject s;
      s["a"] = (int64_t)-1;
      s["b"] = -1.;
      assertException(nm.adjustStates(s));
      Exception::clear();
      */

      DynamicObject expect;
      expect["a"] = (uint64_t)10;
      expect["b"] = (uint64_t)10;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.test("no ex");
   {
      NodeMonitor nm;
      DynamicObject si;
      si["a"]["init"] = (uint64_t)10;
      assertNoException(
         nm.addStates(si));

      DynamicObject s;
      s["bad"] = (int64_t)-1;
      assertException(nm.adjustStates(s));
      Exception::clear();

      DynamicObject expect;
      expect["a"] = (uint64_t)10;

      DynamicObject all = nm.getAll();
      assertDynoCmp(expect, all);
   }
   tr.passIfNoException();

   tr.ungroup();
}
Esempio n. 10
0
bool WebServiceContainer::addService(
   WebServiceRef& service,
   WebService::SecurityType st,
   bool initialize,
   const char* domain)
{
   bool rval = true;

   if(initialize)
   {
      rval = service->initialize();
   }

   if(rval)
   {
      // build list of domains to add service to
      DynamicObject domains(NULL);
      DynamicObject added;
      added->setType(Array);
      if(domain != NULL)
      {
         domains = DynamicObject();
         domains->append(domain);
      }
      else
      {
         domains = mDefaultDomains;
      }

      HttpRequestServicer* hrs = &(*service);
      const char* path = hrs->getPath();

      // prevent other container access
      mContainerLock.lockExclusive();

      DynamicObjectIterator di = domains.getIterator();
      while(rval && di->hasNext())
      {
         const char* dom = di->next()->getString();
         rval = internalAddService(service, st, dom);
         if(rval)
         {
            added->append(dom);
         }
      }

      di = rval ? domains.getIterator() : added.getIterator();
      while(di->hasNext())
      {
         const char* dom = di->next()->getString();

         // success, add domain to http servicer
         if(rval)
         {
            if(st == WebService::Secure || st == WebService::Both)
            {
               mHttpConnectionServicer.addRequestServicer(hrs, true, dom);
               MO_CAT_DEBUG(MO_WS_CAT,
                  "Added secure web service: %s%s", dom, path);
            }
            if(st != WebService::Secure)
            {
               mHttpConnectionServicer.addRequestServicer(hrs, false, dom);
               MO_CAT_DEBUG(MO_WS_CAT,
                  "Added non-secure web service: %s%s", dom, path);
            }
         }
         // could not add service to all domains, so remove it
         else
         {
            internalRemoveService(path, st, dom, NULL);
         }
      }

      // permit access again
      mContainerLock.unlockExclusive();
   }

   // failed to add service
   if(!rval)
   {
      // service was initialized, so clean it up
      if(initialize)
      {
         service->cleanup();
      }

      // set exception
      ExceptionRef e = new Exception(
         "Could not add web service.",
         "monarch.ws.AddWebServiceFailure");
      Exception::push(e);
   }

   return rval;
}
Esempio n. 11
0
bool DomWriter::write(Element& e, OutputStream* os, int level)
{
   DynamicObject nsPrefixMap;
   nsPrefixMap->setType(Map);
   return writeWithNamespaceSupport(e, os, level, nsPrefixMap);
}
Esempio n. 12
0
bool JsonLd::normalize(DynamicObject& in, DynamicObject& out)
{
   bool rval = true;

   // initialize output
   out->setType(Map);
   out->clear();

   // create map to store subjects
   DynamicObject subjects;
   subjects->setType(Map);

   // initialize context
   DynamicObject ctx(NULL);
   if(in->hasMember("#"))
   {
      ctx = in["#"];
   }

   // put all subjects in an array for single code path
   DynamicObject input;
   input->setType(Array);
   if(in->hasMember("@") && in["@"]->getType() == Array)
   {
      input.merge(in["@"], true);
   }
   else
   {
      input->append(in);
   }

   // do normalization
   int bnodeId = 0;
   DynamicObjectIterator i = input.getIterator();
   while(rval && i->hasNext())
   {
      rval = _normalize(ctx, i->next(), &subjects, NULL, bnodeId);
   }

   // build output
   if(rval)
   {
      // single subject
      if(subjects->length() == 1)
      {
         DynamicObject subject = subjects.first();
         out.merge(subject, false);

         // FIXME: will need to check predicates for blank nodes as well...
         // and fail if they aren't embeds?

         // strip blank node '@'
         if(_isBlankNode(out))
         {
            out->removeMember("@");
         }
      }
      // multiple subjects
      else
      {
         DynamicObject& array = out["@"];
         array->setType(Array);
         i = subjects.getIterator();
         while(i->hasNext())
         {
            DynamicObject& next = i->next();

            // FIXME: will need to check predicates for blank nodes as well...
            // and fail if they aren't embeds?

            // strip blank node '@'
            if(_isBlankNode(next))
            {
               next->removeMember("@");
            }
            array->append(next);
         }
      }
   }

   return rval;
}
Esempio n. 13
0
/**
 * Recursively normalizes the given input object.
 *
 * Input: A subject with predicates and possibly embedded other subjects.
 * Output: Either a map of normalized subjects OR a tree of normalized subjects.
 *
 * Normalization Algorithm:
 *
 * Replace the existing context if the input has '#'.
 *
 * For each key-value:
 * 1. Split the key on a colon and look for prefix in the context. If found,
 *    expand the key to an IRI, else it is already an IRI, add <>, save the
 *    new predicate to add to the output.
 * 2. If value is a Map, then it is a subject, set the predicate to the
 *    subject's '@' IRI value and recurse into it. Else goto #3.
 * 3. Look up the key in the context to find type coercion info. If not found,
 *    goto #4, else goto #5.
 * 4. Check the value for an integer, double, or boolean. If matched, set
 *    type according to xsd types. If not matched, look for <>, if found,
 *    do CURIE vs. IRI check like #1 and create appropriate value.
 * 5. If type coercion entry is a string, encode the value using the specific
 *    type. If it is an array, check the type in order of preference. If an
 *    unrecognized type (non-xsd, non-IRI) is provided, throw an exception.
 *
 * @param ctx the context to use (changes during recursion as necessary).
 * @param in the input object.
 * @param subjects a map of normalized subjects.
 * @param out a tree normalized objects.
 * @param bnodeId the last blank node ID used.
 *
 * @return true on success, false on failure with exception set.
 */
static bool _normalize(
   DynamicObject ctx, DynamicObject& in,
   DynamicObject* subjects, DynamicObject* out, int& bnodeId)
{
   bool rval = true;

   // FIXME: validate context (check for non-xsd types in type coercion arrays)

   if(!in.isNull())
   {
      // update context
      if(in->hasMember("#"))
      {
         ctx = in["#"];
      }

      // vars for normalization state
      DynamicObject subject(NULL);
      if(subjects != NULL)
      {
         subject = DynamicObject();
         subject->setType(Map);

         // assign blank node ID as needed
         if(!in->hasMember("@"))
         {
            string bnodeKey = _createBlankNodeId(++bnodeId);
            subject["@"] = bnodeKey.c_str();
         }
      }
      string nKey;

      // iterate over key-values
      DynamicObjectIterator i = in.getIterator();
      while(rval && i->hasNext())
      {
         DynamicObject& value = i->next();
         const char* key = i->getName();

         // skip context keys
         if(key[0] == '#')
         {
            continue;
         }

         // get normalized key
         nKey = _normalizeValue(ctx, key, RDF_TYPE_IRI, NULL, NULL);

         // put values in an array for single code path
         DynamicObject values;
         values->setType(Array);
         if(value->getType() == Array)
         {
            values.merge(value, true);

            // preserve array structure when not using subjects map
            if(out != NULL)
            {
               (*out)[nKey.c_str()]->setType(Array);
            }
         }
         else
         {
            values->append(value);
         }

         // normalize all values
         DynamicObjectIterator vi = values.getIterator();
         while(rval && vi->hasNext())
         {
            DynamicObject v = vi->next();
            if(v->getType() == Map)
            {
               if(subjects != NULL)
               {
                  // get a normalized subject for the value
                  string vSubject;
                  if(v->hasMember("@"))
                  {
                     // normalize existing subject
                     vSubject = _normalizeValue(
                        ctx, v["@"], RDF_TYPE_IRI, NULL, NULL);
                  }
                  else
                  {
                     // generate the next blank node ID in order to preserve
                     // the blank node embed in the code below
                     vSubject = _createBlankNodeId(bnodeId + 1);
                  }

                  // determine if value is a blank node
                  bool isBNode = _isBlankNode(v);

                  // update non-blank node subject (use value's subject IRI)
                  if(!isBNode)
                  {
                     _setPredicate(subject, nKey.c_str(), vSubject.c_str());
                  }

                  // recurse
                  rval = _normalize(ctx, v, subjects, out, bnodeId);

                  // preserve embedded blank node
                  if(rval && isBNode)
                  {
                     // remove embed from top-level subjects
                     DynamicObject embed = (*subjects)[vSubject.c_str()];
                     (*subjects)->removeMember(vSubject.c_str());
                     embed->removeMember("@");
                     _setEmbed(subject, nKey.c_str(), embed);
                  }
               }
               else
               {
                  // update out and recurse
                  DynamicObject next = (*out)[nKey.c_str()];
                  if(value->getType() == Array)
                  {
                     next = next->append();
                  }
                  else
                  {
                     next->setType(Map);
                  }
                  rval = _normalize(ctx, v, subjects, &next, bnodeId);
               }
            }
            else
            {
               _setPredicate(
                  (subjects != NULL) ? subject : *out, nKey.c_str(),
                  _normalizeValue(ctx, v, RDF_TYPE_UNKNOWN, key, NULL).c_str());
            }
         }
      }

      // add subject to map
      if(subjects != NULL)
      {
         (*subjects)[subject["@"]->getString()] = subject;
      }
   }

   return rval;
}
Esempio n. 14
0
void DatabaseClient::buildParams(
   SchemaObject& schema, DynamicObject& members, DynamicObject& params,
   const char* tableAlias)
{
   // ensure params is an array
   params->setType(Array);

   // create shared table alias object
   DynamicObject taObj(NULL);
   if(tableAlias != NULL)
   {
      taObj = DynamicObject();
      taObj = tableAlias;
   }

   // map the given members object into a list of parameters that can
   // be used to generate sql and set parameter values
   DynamicObjectIterator i = schema["columns"].getIterator();
   while(i->hasNext())
   {
      DynamicObject& column = i->next();
      const char* memberName = column["memberName"]->getString();

      // if the members map contains the given member name, create a param
      // for it and append it to the params array
      if(members->hasMember(memberName))
      {
         /* Note: The member value is either a value, map, or an array. If it's
          * an array, then each entry in the array is either a value or a map.
          *
          * Create a single parameter for all values. Create an individual
          * parameter for every map entry. This algorithm will store all maps
          * in "p" and all values in "values". Then "values" will be added to
          * "p". Then a new parameter will be created for each entry in "p".
          */
         DynamicObject& mv = members[memberName];
         DynamicObject p(Array);
         DynamicObject values(Array);

         // group maps and values
         if(mv->getType() == Map)
         {
            p->append(mv);
         }
         else if(mv->getType() == Array)
         {
            DynamicObjectIterator mvi = mv.getIterator();
            while(mvi->hasNext())
            {
               DynamicObject& next = mvi->next();
               if(next->getType() == Map)
               {
                  p->append(next);
               }
               else
               {
                  values->append(next);
               }
            }
         }
         else
         {
            values->append(mv);
         }

         // treat values as a single param
         if(values->length() > 0)
         {
            p->append(values);
         }

         // create params
         DynamicObjectIterator pi = p.getIterator();
         while(pi->hasNext())
         {
            DynamicObject& next = pi->next();

            // add param
            DynamicObject& param = params->append();
            param["name"] = column["name"];
            param["type"] = column["columnType"];
            param["op"] = "=";
            param["boolOp"] = "AND";
            if(column->hasMember("encode"))
            {
               param["encode"] = column["encode"];
            }
            if(tableAlias != NULL)
            {
               param["tableAlias"] = taObj;
            }

            // if next param is a map, get operator and value
            if(next->getType() == Map)
            {
               if(next->hasMember("op"))
               {
                  param["op"] = next["op"].clone();
               }
               if(next->hasMember("boolOp"))
               {
                  param["boolOp"] = next["boolOp"].clone();
               }
               param["value"] = next["value"].clone();
            }
            else
            {
               param["value"] = next.clone();
            }
         }
      }
   }
}