void acStart(const char* name)
{
  ClAmsEntityConfigT n;

  initEntity(&n,name,CL_AMS_ENTITY_TYPE_SG);  
  entityStart(n);
}
void nodeStart(const char* nodeName)
{
  ClAmsEntityConfigT n;

  initEntity(&n,nodeName,CL_AMS_ENTITY_TYPE_NODE);  
  entityStart(n);
}
int main(int argc, char *argv[]) {
  unsigned char c;
  FILE* src = argc >= 2? fopen(argv[1], "rb") : stdin;
  int state = SKIPPING;

  printf("<Entities>\r\n");

  // up to first xml entry
  while (fread(&c, 1, 1, src) == 1) {
    switch (state) {
      case SKIPPING:
        if (entityStart(src, c)) {
          state = CONSUMING;
        }
        break;
      case CONSUMING:
        if (entityEnd(src, c)) {
          state = SKIPPING;
        }
        break;
    }
  }

  printf("</Entities>\r\n");

}
// Create a new Node in the AMF
void addNode(const char* safName)
{
  ClRcT rc;
  ClAmsEntityConfigT entity;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&entity,safName,CL_AMS_ENTITY_TYPE_NODE);
  

  if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&entity)) != CL_OK)
    {
      checkError("Create node",rc);
    }
  
  
  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Commit create node",rc);
    }

  entityStart(entity);  
}
// Start this app container running on these nodes (1+N redundancy).  This will
// start a SAF-aware process on each node specified.
// Create SU and Comp
void acExtend(const char* appCnt, const char* nodeName, const char* compName,SafConfig* cfg)
{
  ClRcT rc;
  ClAmsEntityConfigT  sg;
  ClAmsEntityConfigT  comp;
  ClAmsEntityConfigT su;
  ClUint64T           changeMask = 0;
  
  ClAmsSGConfigT      sgConfig;
  ClAmsEntityConfigT* pEntityConfig = NULL;

  if (ccbHandle==CL_HANDLE_INVALID_VALUE) initHandles();
  initEntity(&sg,appCnt,CL_AMS_ENTITY_TYPE_SG);
  
    
  if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&sg,&pEntityConfig)) != CL_OK)
    {
      checkError("Get SG configuration", rc);
    }

  memcpy(&sgConfig, pEntityConfig, sizeof(sgConfig));
  clHeapFree(pEntityConfig);

  //Fix bug: recovery policy
  if (cfg && cfg->compRestartCountMax > 0 && cfg->compRestartDuration > 0)
    {
      sgConfig.compRestartCountMax = cfg->compRestartCountMax;
      sgConfig.compRestartDuration = cfg->compRestartDuration;
      changeMask |= SG_CONFIG_COMP_RESTART_DURATION | SG_CONFIG_COMP_RESTART_COUNT_MAX;
      if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&sgConfig.entity,changeMask) ) != CL_OK)
        {
          checkError("Set SG config", rc);
        }
    }
  
  // Create SU and component per node
  if (1)
    {
      initEntity(&su,compName,CL_AMS_ENTITY_TYPE_SU);
      if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&su)) != CL_OK)
        {
          checkError("Create SU", rc);
        }
      
      initEntity(&comp,compName,CL_AMS_ENTITY_TYPE_COMP);
      if ((rc = clAmsMgmtCCBEntityCreate(ccbHandle,&comp)) != CL_OK)
        {
          checkError("Create Comp", rc);
        }     
      
    }
  
  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Commit creation of SU and Component", rc);
    }

  SaNameT            supportedCSIType;

  saNameSet(&supportedCSIType, CSI_TYPE_APP);
  supportedCSIType.length += 1;

  // Configure components
  if (1)
    {
      ClAmsCompConfigT   compConfig;
      ClUint64T          bitMask = 0;
      
      if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&comp,&pEntityConfig)) != CL_OK)
        {
          checkError("Retrieve component config", rc);
        }
      memcpy(&compConfig, pEntityConfig, sizeof(compConfig));
      clHeapFree(pEntityConfig);

      bitMask |= COMP_CONFIG_CAPABILITY_MODEL | COMP_CONFIG_TIMEOUTS;

      compConfig.capabilityModel = CL_AMS_COMP_CAP_X_ACTIVE_OR_Y_STANDBY;
      compConfig.timeouts.instantiate = 30000;
      compConfig.timeouts.terminate = 30000;
      compConfig.timeouts.cleanup = 30000;
      compConfig.timeouts.quiescingComplete = 30000;
      compConfig.timeouts.csiSet = 30000;
      compConfig.timeouts.csiRemove = 30000;
      compConfig.timeouts.instantiateDelay = 1000;
      if (!strncmp(nodeName, "sc", 2))
        {    	  
      	  if (cfg && cfg->compRestartCountMax == 0)
      	  {
      		  bitMask |= COMP_CONFIG_IS_RESTARTABLE | COMP_CONFIG_RECOVERY_ON_TIMEOUT;
      		  compConfig.isRestartable = false;
      		  compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NODE_FAILOVER;	     
      	  }    		
      	  else
      	  {    			      	 
      		  bitMask  |= COMP_CONFIG_RECOVERY_ON_TIMEOUT;
      		  compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NO_RECOMMENDATION;	      	 
      	  }
        }
        else
        {
      	  if (cfg && cfg->compRestartCountMax == 0)
      	  {
      		  bitMask |= COMP_CONFIG_IS_RESTARTABLE | COMP_CONFIG_RECOVERY_ON_TIMEOUT;
      		  compConfig.isRestartable = false;
      		  compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_COMP_FAILOVER;	     
      	  }    		
      	  else
      	  {    			      	 
      		  bitMask  |= COMP_CONFIG_RECOVERY_ON_TIMEOUT;
      		  compConfig.recoveryOnTimeout = CL_AMS_RECOVERY_NO_RECOMMENDATION;	      	 
      	  }
        }

      if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK)
        {
        checkError("Set component config", rc);
        }
      
      bitMask = COMP_CONFIG_INSTANTIATE_COMMAND;
      if (cfg&&cfg->binName)
        {
        snprintf(compConfig.instantiateCommand, sizeof(compConfig.instantiateCommand), cfg->binName);
        }
      else
        {
        snprintf(compConfig.instantiateCommand, sizeof(compConfig.instantiateCommand), APP_CNT_CMD);
        }
            
      if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK)
        {
        checkError("Set component instantiate command", rc);          
        }      
    }  

  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Commit configure of components", rc);
    }

    // Configure components
  if (1)
    {
      ClAmsCompConfigT   compConfig;
      ClUint64T          bitMask = 0;
      

      if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&comp,&pEntityConfig)) != CL_OK)
        {
          checkError("Retrieve component config", rc);
        }
      memcpy(&compConfig, pEntityConfig, sizeof(compConfig));
      clHeapFree(pEntityConfig);

      bitMask |= COMP_CONFIG_SUPPORTED_CSI_TYPE | COMP_CONFIG_NUM_MAX_ACTIVE_CSIS | COMP_CONFIG_NUM_MAX_STANDBY_CSIS;

      if(compConfig.pSupportedCSITypes)
        clHeapFree(compConfig.pSupportedCSITypes);
            
      compConfig.numSupportedCSITypes = 1;
      compConfig.pSupportedCSITypes   = &supportedCSIType;
      compConfig.numMaxActiveCSIs     = 10000;
      compConfig.numMaxStandbyCSIs    = 10000;
      
      if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&compConfig.entity,bitMask) ) != CL_OK)
        {
          checkError("Setting supported CSI types", rc);
        }            
    }  

  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Configuring components supported CSI type", rc);
    }

  
  // Configure SUs
  if (1)
    {
      ClUint64T bitMask = 0;
      ClAmsSUConfigT suConfig;

      if ((rc = clAmsMgmtEntityGetConfig(mgmtHandle,&su,&pEntityConfig)) != CL_OK)
        {
          checkError("Get SU", rc);
        }
      
      memcpy(&suConfig, pEntityConfig, sizeof(suConfig));
      clHeapFree(pEntityConfig);

      bitMask |= SU_CONFIG_NUM_COMPONENTS |  SU_CONFIG_ADMIN_STATE;
      // set number of components (processes) per SU to 1
      suConfig.numComponents = 1;
      //suConfig.adminState = CL_AMS_ADMIN_STATE_UNLOCKED;
      suConfig.adminState = CL_AMS_ADMIN_STATE_LOCKED_I;      

      if ((rc = clAmsMgmtCCBEntitySetConfig(ccbHandle,&suConfig.entity,bitMask)) != CL_OK)
        {
           checkError("Configure SU", rc);
         
        }
      // attach the comp to the su
      if ((rc = clAmsMgmtCCBSetSUCompList(ccbHandle,&su,&comp)) != CL_OK)
        {
          checkError("Link COMP to SU", rc);          
        }      
    }

  if ((rc = clAmsMgmtCCBCommit(ccbHandle)) != CL_OK)
    {
      checkError("Commit SU configuration", rc);          
    }

  
  // Add the SU to SG's and Node's list
  if (1)
    {
      ClAmsEntityConfigT node;
      initEntity(&node,nodeName,CL_AMS_ENTITY_TYPE_NODE);

      if ((rc = clAmsMgmtCCBSetSGSUList(ccbHandle,&sg,&su)) != CL_OK)
        {
          checkError("Add SU to SG", rc);
        }

      if ((rc = clAmsMgmtCCBSetNodeSUList(ccbHandle,&node,&su)) != CL_OK)
        {
          checkError("Add SU to Node", rc);
        }

      /*
      if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK)
        {
          checkError("Committing addition of SU to node and SG", rc);
        }
      */

      if ((rc = clAmsMgmtCCBCommit(ccbHandle) ) != CL_OK)
        {
          checkError("Committing addition of SU to node and SG", rc);
        }  
    }

  // Now that all is configured, start them up
  entityStart(su);
}
void suStart(const char* name)
{
  ClAmsEntityConfigT entity;
  initEntity(&entity,name,CL_AMS_ENTITY_TYPE_SU);  
  entityStart(entity);
}