Example #1
0
int 
main(int argc, const char** argv){
  ndb_init();

  
  int _help = 0;
  const char* db = 0;
  const char* connectstring1 = 0;
  const char* connectstring2 = 0;

  struct getargs args[] = {
    { "connectstring1", 'c',
      arg_string, &connectstring1, "connectstring1", "" },
    { "connectstring2", 'C',
      arg_string, &connectstring2, "connectstring2", "" },
    { "database", 'd', arg_string, &db, "Database", "" },
    { "usage", '?', arg_flag, &_help, "Print help", "" }
  };
  int num_args = sizeof(args) / sizeof(args[0]);
  int optind = 0, i;
  char desc[] = 
    "<tabname>+ \nThis program listen to events on specified tables\n";
  
  if(getarg(args, num_args, argc, argv, &optind) ||
     argv[optind] == NULL || _help) {
    arg_printusage(args, num_args, argv[0], desc);
    return NDBT_ProgramExit(NDBT_WRONGARGS);
  }

  // Connect to Ndb
  Ndb_cluster_connection con(connectstring1);
  if(con.connect(12, 5, 1) != 0)
  {
    return NDBT_ProgramExit(NDBT_FAILED);
  }
  Ndb MyNdb( &con, db ? db : "TEST_DB" );

  if(MyNdb.init() != 0){
    ERR(MyNdb.getNdbError());
    return NDBT_ProgramExit(NDBT_FAILED);
  }

  // Connect to Ndb and wait for it to become ready
  while(MyNdb.waitUntilReady() != 0)
    ndbout << "Waiting for ndb to become ready..." << endl;

  Ndb_cluster_connection *con2 = NULL;
  Ndb *ndb2 =  NULL;
  if (connectstring2)
  {
    con2 = new Ndb_cluster_connection(connectstring2);

    if(con2->connect(12, 5, 1) != 0)
    {
      return NDBT_ProgramExit(NDBT_FAILED);
    }
    ndb2 = new Ndb( con2, db ? db : "TEST_DB" );

    if(ndb2->init() != 0){
      ERR(ndb2->getNdbError());
      return NDBT_ProgramExit(NDBT_FAILED);
    }

    // Connect to Ndb and wait for it to become ready
    while(ndb2->waitUntilReady() != 0)
      ndbout << "Waiting for ndb to become ready..." << endl;
  }

  int result = 0;
  
  NdbDictionary::Dictionary *myDict = MyNdb.getDictionary();
  Vector<NdbDictionary::Event*> events;
  Vector<NdbEventOperation*> event_ops;
  int sz = 0;
  for(i= optind; i<argc; i++)
  {
    const NdbDictionary::Table* table= myDict->getTable(argv[i]);
    if(!table)
    {
      ndbout_c("Could not find table: %s, skipping", argv[i]);
      continue;
    }

    BaseString name;
    name.appfmt("EV-%s", argv[i]);
    NdbDictionary::Event *myEvent= new NdbDictionary::Event(name.c_str());
    myEvent->setTable(table->getName());
    myEvent->addTableEvent(NdbDictionary::Event::TE_ALL); 
    for(int a = 0; a < table->getNoOfColumns(); a++){
      myEvent->addEventColumn(a);
    }

    if (myDict->createEvent(* myEvent))
    {
      if(myDict->getNdbError().classification == NdbError::SchemaObjectExists) 
      {
	g_info << "Event creation failed event exists. Removing...\n";
	if (myDict->dropEvent(name.c_str()))
	{
	  g_err << "Failed to drop event: " << myDict->getNdbError() << endl;
	  result = 1;
	  goto end;
	}
	// try again
	if (myDict->createEvent(* myEvent)) 
	{
	  g_err << "Failed to create event: " << myDict->getNdbError() << endl;
	  result = 1;
	  goto end;
	}
      }
      else
      {
	g_err << "Failed to create event: " << myDict->getNdbError() << endl;
	result = 1;
	goto end;
      }
    }
    
    events.push_back(myEvent);

    NdbEventOperation* pOp = MyNdb.createEventOperation(name.c_str());
    if ( pOp == NULL ) {
      g_err << "Event operation creation failed" << endl;
      result = 1;
      goto end;
    }

    event_values.push_back(Vector<NdbRecAttr *>());
    event_pre_values.push_back(Vector<NdbRecAttr *>());
    for (int a = 0; a < table->getNoOfColumns(); a++) 
    {
      event_values[sz].
        push_back(pOp->getValue(table->getColumn(a)->getName()));
      event_pre_values[sz].
        push_back(pOp->getPreValue(table->getColumn(a)->getName()));
    }
    event_ops.push_back(pOp);
    {
      struct Table_info ti;
      ti.id = sz;
      table_infos.push_back(ti);
    }
    pOp->setCustomData((void *)&table_infos[sz]);
    sz++;
  }

  for(i= 0; i<(int)event_ops.size(); i++)
  {
    if (event_ops[i]->execute())
    { 
      g_err << "operation execution failed: " << event_ops[i]->getNdbError()
	    << endl;
      result = 1;
      goto end;
    }
  }

  struct Trans_arg trans_arg;
  while(true)
  {
    while(MyNdb.pollEvents(100) == 0);
    
    NdbEventOperation* pOp= MyNdb.nextEvent();
    while(pOp)
    {
      Uint64 gci= pOp->getGCI();
      Uint64 cnt_i= 0, cnt_u= 0, cnt_d= 0;
      if (ndb2)
        do_begin(ndb2, trans_arg);
      do
      {
	switch(pOp->getEventType())
	{
	case NdbDictionary::Event::TE_INSERT:
	  cnt_i++;
          if (ndb2)
            do_insert(trans_arg, pOp);
	  break;
	case NdbDictionary::Event::TE_DELETE:
	  cnt_d++;
          if (ndb2)
            do_delete(trans_arg, pOp);
	  break;
	case NdbDictionary::Event::TE_UPDATE:
	  cnt_u++;
          if (ndb2)
            do_update(trans_arg, pOp);
	  break;
	case NdbDictionary::Event::TE_CLUSTER_FAILURE:
	  break;
	case NdbDictionary::Event::TE_ALTER:
	  break;
	case NdbDictionary::Event::TE_DROP:
	  break;
	case NdbDictionary::Event::TE_NODE_FAILURE:
	  break;
	case NdbDictionary::Event::TE_SUBSCRIBE:
	case NdbDictionary::Event::TE_UNSUBSCRIBE:
	  break;
	default:
	  /* We should REALLY never get here. */
	  ndbout_c("Error: unknown event type: %u", 
		   (Uint32)pOp->getEventType());
	  abort();
	}
      } while ((pOp= MyNdb.nextEvent()) && gci == pOp->getGCI());
      if (ndb2)
        do_commit(trans_arg);
      ndbout_c("GCI: %lld events: %lld(I) %lld(U) %lld(D)", gci, cnt_i, cnt_u, cnt_d);
    }
  }
end:
  for(i= 0; i<(int)event_ops.size(); i++)
    MyNdb.dropEventOperation(event_ops[i]);

  if (ndb2)
    delete ndb2;
  if (con2)
    delete con2;
  return NDBT_ProgramExit(NDBT_OK);
}
Example #2
0
 NodeType(Uint32 node_type) {
   const char* str= NULL;
   const char* alias=
     ndb_mgm_get_node_type_alias_string((ndb_mgm_node_type)node_type, &str);
   m_str.assfmt("%s(%s)", alias, str);
 }
Example #3
0
 const char* c_str() { return m_str.c_str(); }
Example #4
0
static inline int sh(const char *script){

#ifdef _WIN32
  g_logger.debug("sh('%s')", script);

  /*
    Running sh script on Windows
    1) Write the command to run into temporary file
    2) Run the temporary file with 'sh <temp_file_name>'
  */

  char tmp_path[MAX_PATH];
  if (GetTempPath(sizeof(tmp_path), tmp_path) == 0)
  {
    g_logger.error( "GetTempPath failed, error: %d", GetLastError());
    return -1;
  }

  char tmp_file[MAX_PATH];
  if (GetTempFileName(tmp_path, "sh_", 0, tmp_file) == 0)
  {
    g_logger.error( "GetTempFileName failed, error: %d", GetLastError());
    return -1;
  }

  FILE* fp = fopen(tmp_file, "w");
  if (fp == NULL)
  {
    g_logger.error( "Cannot open file '%s', error: %d", tmp_file, errno);
    return -1;
  }

  // cygwin'ify the script and write it to temp file
  {
    char* cygwin_script = replace_drive_letters(script);
    g_logger.debug(" - cygwin_script: '%s' ", cygwin_script);
    fprintf(fp, "%s", cygwin_script);
    free(cygwin_script);
  }

  fclose(fp);

  // Run the temp file with "sh"
  BaseString command;
  command.assfmt("sh %s", tmp_file);
  g_logger.debug(" - running '%s' ", command.c_str());

  int ret = system(command.c_str());
  if (ret == 0)
    g_logger.debug(" - OK!");
  else
    g_logger.warning("Running the command '%s' as '%s' failed, ret: %d",
                     script, command.c_str(), ret);

  // Remove the temp file
  unlink(tmp_file);

  return ret;

#else

  return system(script);

#endif

}
Example #5
0
  bool call(const char* cmd, const Properties& args,
            const char* cmd_reply, Properties& reply,
            const char* bulk = NULL,
            bool name_value_pairs = true){

    if (!is_connected()){
      error("call: not connected");
      return false;
    }

    SocketOutputStream out(socket());

    if (out.println("%s", cmd)){
      error("call: println failed at line %d", __LINE__);
      return false;
    }

    Properties::Iterator iter(&args);
    const char *name;
    while((name = iter.next()) != NULL) {
      PropertiesType t;
      Uint32 val_i;
      Uint64 val_64;
      BaseString val_s;

      args.getTypeOf(name, &t);
      switch(t) {
      case PropertiesType_Uint32:
	args.get(name, &val_i);
	if (out.println("%s: %d", name, val_i)){
          error("call: println failed at line %d", __LINE__);
          return false;
        }
	break;
      case PropertiesType_Uint64:
	args.get(name, &val_64);
	if (out.println("%s: %Ld", name, val_64)){
          error("call: println failed at line %d", __LINE__);
          return false;
        }
	break;
      case PropertiesType_char:
	args.get(name, val_s);
	if (out.println("%s: %s", name, val_s.c_str())){
          error("call: println failed at line %d", __LINE__);
          return false;
        }
	break;
      default:
      case PropertiesType_Properties:
	/* Illegal */
        abort();
	break;
      }
    }

    // Emtpy line terminates argument list
    if (out.print("\n")){
      error("call: print('\n') failed at line %d", __LINE__);
      return false;
    }

    // Send any bulk data
    if (bulk)
    {
      if (out.write(bulk, strlen(bulk)) >= 0)
      {
        if (out.write("\n", 1) < 0)
        {
          error("call: print('<bulk>') failed at line %d", __LINE__);
          return false;
        }
      }
    }

    BaseString buf;
    SocketInputStream2 in(socket());
    if (cmd_reply)
    {
      // Read the reply header and compare against "cmd_reply"
      if (!in.gets(buf)){
        error("call: could not read reply command");
        return false;
      }

      // 1. Check correct reply header
      if (buf != cmd_reply){
        error("call: unexpected reply command, expected: '%s', got '%s'",
              cmd_reply, buf.c_str());
        return false;
      }
    }

    // 2. Read lines until empty line
    int line = 1;
    while(in.gets(buf)){

      // empty line -> end of reply
      if (buf == "")
        return true;

      if (name_value_pairs)
      {
        // 3a. Read colon separated name value pair, split
        // the name value pair on first ':'
        Vector<BaseString> name_value_pair;
        if (buf.split(name_value_pair, ":", 2) != 2){
          error("call: illegal name value pair '%s' received", buf.c_str());
          return false;
        }

        reply.put(name_value_pair[0].trim(" ").c_str(),
                  name_value_pair[1].trim(" ").c_str());
      }
      else
      {
        // 3b. Not name value pair, save the line into "reply"
        // using unique key
        reply.put("line", line++, buf.c_str());
      }
    }

    error("call: should never come here");
    reply.print();
    abort();
    return false;
  }
Example #6
0
 virtual void info(BaseString &pMsg) const { info(pMsg.c_str()); };
Example #7
0
 virtual void debug(BaseString &pMsg) const { debug(pMsg.c_str()); };
Example #8
0
 virtual void error(BaseString &pMsg) const { error(pMsg.c_str()); };
Example #9
0
 virtual void warning(BaseString &pMsg) const { warning(pMsg.c_str()); };
Example #10
0
 virtual void alert(BaseString &pMsg) const { alert(pMsg.c_str()); };
Example #11
0
 virtual void critical(BaseString &pMsg) const { critical(pMsg.c_str()); };
Example #12
0
bool
ConfigRetriever::verifyConfig(const struct ndb_mgm_configuration * conf,
                              Uint32 nodeid)
{
  char buf[255];
  ndb_mgm_configuration_iterator it(* conf, CFG_SECTION_NODE);

  if(it.find(CFG_NODE_ID, nodeid)){
    BaseString::snprintf(buf, 255, "Unable to find node with id: %d", nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  const char * hostname;
  if(it.get(CFG_NODE_HOST, &hostname)){
    BaseString::snprintf(buf, 255, "Unable to get hostname(%d) from config",
                         CFG_NODE_HOST);
    setError(CR_ERROR, buf);
    return false;
  }

  if (hostname && hostname[0] != 0 &&
      !SocketServer::tryBind(0,hostname)) {
    BaseString::snprintf(buf, 255,
                         "The hostname this node should have according "
                         "to the configuration does not match a local "
                         "interface. Attempt to bind '%s' "
                         "failed with error: %d '%s'",
                         hostname, errno, strerror(errno));
    setError(CR_ERROR, buf);
    return false;
  }

  unsigned int _type;
  if(it.get(CFG_TYPE_OF_SECTION, &_type)){
    BaseString::snprintf(buf, 255, "Unable to get type of node(%d) from config",
                         CFG_TYPE_OF_SECTION);
    setError(CR_ERROR, buf);
    return false;
  }

  if(_type != (unsigned int)m_node_type){
    const char *type_s, *alias_s, *type_s2, *alias_s2;
    alias_s=
      ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)m_node_type,
                                         &type_s);
    alias_s2=
      ndb_mgm_get_node_type_alias_string((enum ndb_mgm_node_type)_type,
                                         &type_s2);
    BaseString::snprintf(buf, 255,
                         "This node type %s(%s) and config "
			 "node type %s(%s) don't match for nodeid %d",
			 alias_s, type_s, alias_s2, type_s2, nodeid);
    setError(CR_ERROR, buf);
    return false;
  }

  /**
   * Check hostnames
   */
  ndb_mgm_configuration_iterator iter(* conf, CFG_SECTION_CONNECTION);
  for(iter.first(); iter.valid(); iter.next()){

    Uint32 type = CONNECTION_TYPE_TCP + 1;
    if(iter.get(CFG_TYPE_OF_SECTION, &type)) continue;
    if(type != CONNECTION_TYPE_TCP) continue;
    
    Uint32 nodeId1, nodeId2, remoteNodeId;
    if(iter.get(CFG_CONNECTION_NODE_1, &nodeId1)) continue;
    if(iter.get(CFG_CONNECTION_NODE_2, &nodeId2)) continue;
    
    if(nodeId1 != nodeid && nodeId2 != nodeid) continue;
    remoteNodeId = (nodeid == nodeId1 ? nodeId2 : nodeId1);

    const char * name;
    struct in_addr addr;
    BaseString tmp;
    if(!iter.get(CFG_CONNECTION_HOSTNAME_1, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }

    if(!iter.get(CFG_CONNECTION_HOSTNAME_2, &name) && strlen(name)){
      if(Ndb_getInAddr(&addr, name) != 0){
	tmp.assfmt("Unable to lookup/illegal hostname %s, "
		   "connection from node %d to node %d",
		   name, nodeid, remoteNodeId);
	setError(CR_ERROR, tmp.c_str());
	return false;
      }
    }
  }

  return true;
}
Example #13
0
void
ConfigRetriever::setError(ErrorType et, BaseString err){
  setError(et, err.c_str());
}
Example #14
0
bool
CPCD::loadProcessList(){
  BaseString secondfile;
  FILE *f;

  loadingProcessList = true;

  secondfile.assfmt("%s.new", m_procfile.c_str());

  /* Try to open the config file */
  f = fopen(m_procfile.c_str(), "r");

  /* If it did not exist, try to open the backup. See the saveProcessList()
   * method for an explanation why it is done this way.
   */
  if(f == NULL) {
    f = fopen(secondfile.c_str(), "r");
    
    if(f == NULL) {
      /* XXX What to do here? */
      logger.info("Configuration file `%s' not found",
		  m_procfile.c_str());
      logger.info("Starting with empty configuration");
      loadingProcessList = false;
      return false;
    } else {
      logger.info("Configuration file `%s' missing",
		  m_procfile.c_str());
      logger.info("Backup configuration file `%s' is used",
		  secondfile.c_str());
      /* XXX Maybe we should just rename the backup file to the official
       * name, and be done with it?
       */
    }
  }

/*
  File is ignored anyways, so don't load it,
  kept for future use of config file.

  CPCDAPISession sess(f, *this);
  sess.loadFile();
*/
  fclose(f);
  loadingProcessList = false;

  unsigned i;
  Vector<int> temporary;
  for(i = 0; i<m_processes.size(); i++){
    Process * proc = m_processes[i];
    proc->readPid();
    if(proc->m_processType == TEMPORARY){
      temporary.push_back(proc->m_id);
    }
  }
  
  for(i = 0; i<temporary.size(); i++){
    RequestStatus rs;
    undefineProcess(&rs, temporary[i]);
  }
  
  /* Don't call notifyChanges here, as that would save the file we just
     loaded */
  m_monitor->signal();
  return true;
}
Example #15
0
int
main(int argc, const char** argv){
  ndb_init();
  int verbose = 1;
  int optind = 0;
  
  struct getargs args[1+P_MAX] = {
    { "verbose", 'v', arg_flag, &verbose, "Print verbose status", "verbose" }
  };
  const int num_args = 1 + P_MAX;
  int i;
  for(i = 0; i<P_MAX; i++){
    args[i+1].long_name = g_paramters[i].name;
    args[i+1].short_name = * g_paramters[i].name;
    args[i+1].type = arg_integer;
    args[i+1].value = &g_paramters[i].value;
    BaseString tmp;
    tmp.assfmt("min: %d max: %d", g_paramters[i].min, g_paramters[i].max);
    args[i+1].help = strdup(tmp.c_str());
    args[i+1].arg_help = 0;
  }
  
  if(getarg(args, num_args, argc, argv, &optind)) {
    arg_printusage(args, num_args, argv[0], "tabname1 tabname2 ...");
    return NDBT_WRONGARGS;
  }
  
  myRandom48Init(NdbTick_CurrentMillisecond());
  memset(g_times, 0, sizeof(g_times));

  Ndb_cluster_connection con;
  if(con.connect(12, 5, 1))
  {
    return NDBT_ProgramExit(NDBT_FAILED);
  }

  g_ndb = new Ndb(&con, "TEST_DB");
  if(g_ndb->init() != 0){
    g_err << "init() failed" << endl;
    goto error;
  }
  if(g_ndb->waitUntilReady() != 0){
    g_err << "Wait until ready failed" << endl;
    goto error;
  }
  for(i = optind; i<argc; i++){
    const char * T = argv[i];
    g_info << "Testing " << T << endl;
    BaseString::snprintf(g_table, sizeof(g_table), T);
    BaseString::snprintf(g_ordered, sizeof(g_ordered), "IDX_O_%s", T);
    BaseString::snprintf(g_unique, sizeof(g_unique), "IDX_U_%s", T);
    if(create_table())
      goto error;
    if(load_table())
      goto error;
    for(int l = 0; l<g_paramters[P_LOOPS].value; l++){
      for(int j = 0; j<P_OP_TYPES; j++){
	g_paramters[P_OPER].value = j;
	if(run_read())
	  goto error;
      }
    }
    print_result();
  }
  
  if(g_ndb) delete g_ndb;
  return NDBT_OK;
error:
  if(g_ndb) delete g_ndb;
  return NDBT_FAILED;
}
Example #16
0
 SavedRecord(int _gci, BaseString _str){ 
   m_gci = _gci; 
   m_str.assign(_str); 
 }