浏览代码

Incorporate changes based on feedback
- Common up and refactor code for Hardware and Software copy
- Refactor iterator syntax
- Remove unused variable
- Remove extraneous code

Signed-off-by: Gleb Aronsky <gleb.aronsky@lexisnexis.com>

Gleb Aronsky 13 年之前
父节点
当前提交
d6af5dcd05

+ 1 - 0
deployment/deploy/XMLTags.h

@@ -161,6 +161,7 @@
 #define XML_ATTR_MULTISLAVES           "@multiSlaves"
 #define XML_ATTR_MYSQL                 "@mysql"
 #define XML_ATTR_NAME                  "@name"
+#define XML_ATTR_TARGET                "@target"
 #define XML_ATTR_NAMESERVICES          "@nameServices"
 #define XML_ATTR_NETADDRESS            "@netAddress"
 #define XML_ATTR_NICSPEED              "@nicSpeed"

+ 4 - 0
deployment/deploy/deploy.cpp

@@ -1185,6 +1185,10 @@ IPropertyTree* getInstances(const IPropertyTree* pEnvRoot, const char* compName,
           {
             sXPath.clear().appendf("Hardware/Computer[@name=\"%s\"]", computer);
             IPropertyTree* pComputer = pEnvRoot->queryPropTree(sXPath.str());
+
+            if (pComputer == NULL)
+              throw MakeStringException(-1,"XPATH: %s is invalid.\n(Did you configure the Hardware?)", sXPath.str());
+
             netAddr = pComputer->queryProp("@netAddress");
             if (matchDeployAddress(ipAddr, netAddr) || 
                 (!ipAddr && netAddr && *netAddr))

+ 108 - 12
esp/files/scripts/configmgr/navtree.js

@@ -391,7 +391,7 @@ function createNavigationTree(navTreeData) {
                   hasChildren = {};
                 hasChildren[prnt] = true;
                 return true;
-              }, width: "100%", selectionMode:"single"
+              }, width: "100%"
             }
         );
 
@@ -759,6 +759,10 @@ function createNavigationTree(navTreeData) {
       },
         getFileName(true) + 'Operation=Duplicate&XmlArgs=' + xmlStr);
     }
+    else if (p_oValue.parent.id ==="HWCopy" || p_oValue.parent.id === "SWCopy")
+    {
+      copyHWSWTo(menuItemName, (p_oValue.parent.id === "HWCopy" ? true : false) );
+    }
     else {
       var xmlStr = "<Components><Component buildSet='" + menuItemName + "'/></Components>";
       YAHOO.util.Connect.asyncRequest('POST', '/WsDeploy/HandleComponent', {
@@ -772,14 +776,6 @@ function createNavigationTree(navTreeData) {
               top.document.lastSelectedRow = temp1[0];
               getWaitDlg().hide();
               navDS.flushCache();
-
-              //                 var tid= YAHOO.util.Get.script('/esp/files/scripts/navtreedata.js',{ 
-              //                   onSuccess: function(obj) {
-              //                     var parsedResults = navDS.parseArrayData(o, navTreeData);
-              //                     navDS.handleResponse("", parsedResults.results, {   success:navDT.onDataReturnInitializeTable,
-              //                                                 scope:navDT}, this, 999);
-              //                   }
-              //                  });
               refreshNavTree(navDS, navDT)
             }
             else if (o.responseText.indexOf("<html") === 0) {
@@ -812,6 +808,8 @@ function createNavigationTree(navTreeData) {
     else if (menuItemName === 'Save Environment As...') {
       saveEnvironmentAs();
     }
+    else if (menuItemName == 'Copy Hardware To')
+      copyHWSWTo(menuItemName, true);
     else if (menuItemName === 'Validate Environment')
       validateEnvironment();
     else if (menuItemName === 'Deploy...') {
@@ -1107,6 +1105,40 @@ function createNavigationTree(navTreeData) {
     }
   }
 
+  var copyCompMenu = new Array();
+  var fnDeleteComps = function(){
+  var params = "queryType=sourceEnvironments";
+
+  YAHOO.util.Connect.asyncRequest('POST', '/WsDeploy/GetValue', {
+    success: function(o) {
+        if (o.responseText.indexOf("<?xml") === 0) {
+      var tmp = o.responseText.split(/<ReqValue>/g);
+      var tmp1;
+      if (tmp.length > 1) {
+        tmp1 = tmp[1].split(/<\/ReqValue>/g);
+        if (tmp1.length > 1)
+          result = tmp1[0];
+        else
+          result = '';
+        }
+        var files = result.split(/;/g);
+        for (var i = 0; i < files.length; i++) {
+          if( files[i]  ==  "<StagedConfiguration>" || files[i] == "</StagedConfiguration" || files[i] == "")
+            {
+               continue;
+            }
+           copyCompMenu[i] = { text: files[i], onclick: { fn: onMenuSWClick} };
+          }
+        }
+      },
+      failure: function(o) {
+      },
+      scope: this
+    },
+  getFileName(true) + 'Params=' + params);
+  }
+  fnDeleteComps();
+
   var compMenu = new Array();
   for (i = 0; i < navDT.navTreeData[0]["menuComps"].length; i++)
     compMenu[i] = { text: navDT.navTreeData[0]["menuComps"][i], onclick: { fn: onMenuSWClick} };
@@ -1117,8 +1149,15 @@ function createNavigationTree(navTreeData) {
 
   var oContextMenuItems = {
     "Environment": [{text: "Save Environment", onclick: { fn: onMenuItemClick } },
-                    { text: "Save Environment As...", onclick: { fn: onMenuItemClick } },
-                    {text: "Validate Environment", onclick: { fn: onMenuItemClick } }
+                    {text: "Save Environment As...", onclick: { fn: onMenuItemClick } },
+                    {text: "Validate Environment", onclick: { fn: onMenuItemClick } },
+                    {text: "Copy Hardware To",
+                      submenu: {
+                           id: "HWCopy",
+                           lazyload: true,
+                           itemdata: copyCompMenu,
+                           onclick: { fn: onMenuItemClick },
+                          } }
                           ],
     "Hardware": [
                               "New",
@@ -1159,7 +1198,14 @@ function createNavigationTree(navTreeData) {
                                 onclick: { fn: onMenuSWClick }
                               },
                               { text: "Delete Component/Service", onclick: { fn: onMenuSWClick} },
-                              { text: "Duplicate Component/Service", onclick: { fn: onMenuSWClick} }
+                              { text: "Duplicate Component/Service", onclick: { fn: onMenuSWClick} },
+                              { text: "Copy Component/Service To",
+                                submenu: {
+                                  id: "SWCopy",
+                                  lazyload: true,
+                                  itemdata: copyCompMenu
+                                 },
+                              }
                           ],
     "Columns": [
                               {
@@ -1843,6 +1889,56 @@ function saveEnvironment(saveas) {
   getFileName(true) + args);
 }
 
+copyHWSWTo = function (menuItemName, IsHW)
+{
+  var targetRec;
+  var xmlStr = "";
+  var xmlStr2 = "";
+  var idx;
+
+  if (IsHW === true)
+  {
+    xmlStr2 = "<Components> <Component name=\"Hardware\" target=\"" + menuItemName + "\"/> " + "</Components>";
+  }
+  else // software
+  {
+    xmlStr = top.document.navDT.selectionToXML(targetRec, top.document.navDT.getSelectedRows(), targetRec, "Components");
+    idx = xmlStr.indexOf("build");
+    xmlStr2 = xmlStr.substr(0,idx-1) + " target=\"" + menuItemName + "\" " + xmlStr.substr(idx,xmlStr.length);
+  }
+
+  YAHOO.util.Connect.asyncRequest('POST', '/WsDeploy/HandleComponent', {
+    success: function(o)
+    {
+      if (o.status === 200)
+      {
+        if (o.responseText.indexOf("<?xml") === 0)
+        {
+          var form = document.forms['treeForm'];
+          form.isChanged.value = "true";
+          var temp = o.responseText.split(/<CompName>/g);
+          var temp1 = temp[1].split(/<\/CompName>/g);
+          top.document.lastSelectedRow = temp1[0];
+          getWaitDlg().hide();
+        }
+        else if (o.responseText.indexOf("<html") === 0)
+        {
+          var temp = o.responseText.split(/td align=\"left\">/g);
+          var temp1 = temp[1].split(/<\/td>/g);
+          getWaitDlg().hide();
+          alert(temp1[0]);
+        }
+      }
+    },
+    failure: function(o) {
+      getWaitDlg().hide();
+      alert(o.statusText);
+    },
+    scope: this
+  },
+  getFileName(true) + 'Operation=Copy' + (IsHW ? 'HW' : 'SW') + '&XmlArgs='  + xmlStr2);
+}
+
 function saveEnvironmentAs() {
   var handleCancel = function() {
     getWaitDlg().hide();

+ 170 - 2
esp/services/WsDeploy/WsDeployService.cpp

@@ -3314,6 +3314,10 @@ bool CWsDeployFileInfo::displaySettings(IEspContext &context, IEspDisplaySetting
               {
                 xpath.clear().appendf("Hardware/Computer/[@name='%s']", pszComputer);
                 IPropertyTree* pComputer= pEnvRoot->queryPropTree(xpath.str());
+
+                if (pComputer == NULL)
+                  throw MakeStringException(-1, "XPATH: %s is invalid. (Did you add the Hardware?)",xpath.str());
+
                 const char* pszNetAddr = pComputer->queryProp(XML_ATTR_NETADDRESS);
                 if (pszNetAddr)
                   pMasterNode->addProp(XML_ATTR_NETADDRESS, pszNetAddr);
@@ -4210,6 +4214,159 @@ bool CWsDeployFileInfo::handleComponent(IEspContext &context, IEspHandleComponen
     }
     resp.setCompName(XML_TAG_SOFTWARE);
   }
+  else if (!strcmp(operation, "CopySW"))
+  {
+    if (handleComponentCopy(pComponents, pEnvRoot.get()) == true)
+      resp.setStatus("true");
+    else
+      resp.setStatus("false");
+  }
+  else if (!strcmp(operation, "CopyHW"))
+  {
+    if (handleHardwareCopy(pComponents, pEnvRoot->queryPropTree("Hardware"))== true)
+      resp.setStatus("true");
+    else
+      resp.setStatus("false");
+  }
+  return true;
+}
+
+bool CWsDeployFileInfo::handleHardwareCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot)
+{
+  StringBuffer xpath;
+  StringBuffer filePath;
+  xpath.clear().appendf("%s", XML_TAG_HARDWARE);
+
+  Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
+  Owned<IPropertyTreeIterator> iter = pEnvRoot->getElements("*");
+
+  if (!iterComp->first())
+    return false;
+
+  CWsDeployFileInfo::setFilePath(filePath, iterComp->query().queryProp(XML_ATTR_TARGET));
+
+  Owned<CWsDeployFileInfo> fi = new CWsDeployFileInfo(m_pService, filePath, false);
+
+  fi->m_skipEnvUpdateFromNotification = false;
+  fi->initFileInfo(false,false);
+  Owned<IPropertyTree> pEnvRoot2 = &(fi->m_Environment->getPTree());
+  bool bWrite = false;
+
+  ForEach(*iter)
+  {
+    IPropertyTree& pComp = iter->query();
+    const char* name = pComp.queryProp(XML_ATTR_NAME);
+    const char* tag_name = pComp.queryName();
+    StringBuffer xml;
+
+    xml.appendf("<%s", tag_name);
+    Owned<IAttributeIterator> pAttribIter = pComp.getAttributes();
+
+    ForEach(*pAttribIter)
+    {
+      const char* name = &(pAttribIter->queryName()[1]);
+      const char* value = pAttribIter->queryValue();
+
+      xml.appendf(" %s=\"%s\" ", name, value);
+    }
+    xml.append("/>");
+
+    IPropertyTree *dupTree = createPTreeFromXMLString(xml.str());
+
+    StringBuffer xpath2;
+    xpath2.appendf("./%s/%s[%s = \"%s\"]", XML_TAG_HARDWARE, tag_name, XML_ATTR_NAME, name);
+
+    if (pEnvRoot2->queryPropTree(xpath2.str()) != NULL) // check if target configuration has same named element
+    {
+      continue;
+    }
+
+    bWrite = true;
+
+    StringBuffer strTag;
+    strTag.clear().appendf("%s/%s", XML_TAG_HARDWARE, tag_name);
+
+    if (pEnvRoot2->addPropTree(strTag.str(), dupTree) == NULL)
+      return false;
+  }
+
+  if (bWrite == true)
+  {
+    StringBuffer err;
+    fi->saveEnvironment(NULL, NULL, err);
+    throw MakeStringException(-1, "Saved succeeded but some some element(s) could not be copied.  Element(s) may already exist in the target configuration.");
+  }
+
+  return true;
+}
+
+bool CWsDeployFileInfo::handleComponentCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot)
+{
+  Owned<IPropertyTreeIterator> iterComp = pComponents->getElements("*");
+  bool bError = false;
+  StringBuffer errMsg;
+
+  char targetName[255] = "";
+  iterComp->first();
+  strncpy(targetName, iterComp->query().queryProp("@target"), 255);  //get the copy target configuration file name
+
+  StringBuffer filePath;
+  CWsDeployFileInfo::setFilePath(filePath, targetName);
+
+  Owned<CWsDeployFileInfo> fi = new CWsDeployFileInfo(m_pService, filePath, false);
+
+  fi->m_skipEnvUpdateFromNotification = false;
+  fi->initFileInfo(false,false);
+
+  Owned<IPropertyTree> pEnvRoot2 = &(fi->m_Environment->getPTree());
+  Owned<IPropertyTreeIterator> iterComp2 = pComponents->getElements("*");
+
+  StringBuffer xpath;
+
+  ForEach(*iterComp)
+  {
+    IPropertyTree& pComp = iterComp->query();
+    const char* compName = pComp.queryProp(XML_ATTR_NAME);
+
+    if (compName == NULL)
+    {
+      if (bError == false)
+      {
+        bError = true;
+        errMsg.clear().appendf("Faild to query for @name attribute, continuing...");
+      }
+      continue;
+    }
+
+    const char* compType = pComp.queryProp("@compType");
+    StringBuffer sbNewName = compName;
+
+    xpath.clear().appendf("%s", compType);
+    getUniqueName(pEnvRoot2, sbNewName, xpath.str(), XML_TAG_SOFTWARE);
+    xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, compName);
+    IPropertyTree* pCompTree = pEnvRoot->queryPropTree(xpath.str());
+
+    if ( pCompTree == NULL)
+      throw MakeStringException(-1,"XPATH: %s is invalid in source configuration. Copy failed.", xpath.str());
+
+    xpath.clear().appendf("./%s/%s[%s=\"%s\"]", XML_TAG_SOFTWARE, compType, XML_ATTR_NAME, sbNewName.str());
+    StringBuffer xml;
+
+    toXML(pCompTree, xml);
+
+    IPropertyTree *dupTree = createPTreeFromXMLString(xml.str());
+    dupTree->setProp(XML_ATTR_NAME, sbNewName.str());
+
+    if (pEnvRoot2->addPropTree(xpath, dupTree) == NULL)
+      throw MakeStringException(-1,"XPATH: %s is invalid in target. Copy failed.", xpath.str());
+  }
+
+  StringBuffer err;
+  fi->saveEnvironment(NULL, NULL, err);
+
+  if (bError == true)
+    throw MakeStringException(-1,"Save succeeded but an error was encountered with message: %s", errMsg.str());
+
   return true;
 }
 
@@ -5294,6 +5451,16 @@ const char* CWsDeployFileInfo::GetDisplayProcessName(const char* processName, ch
   }
 }
 
+void CWsDeployFileInfo::setFilePath(StringBuffer &filePath, const char* targetName)
+{
+  filePath.clear().append(CONFIG_SOURCE_DIR);
+
+  if (filePath.charAt(filePath.length() - 1) != PATHSEPCHAR)
+    filePath.append(PATHSEPCHAR);
+
+  filePath.append(targetName);
+}
+
 void CWsDeployFileInfo::updateConfigFromFile()
 {
   StringBuffer sbxml;
@@ -5988,7 +6155,7 @@ bool CWsDeployFileInfo::getSummary(IEspContext &context, IEspGetSummaryRequest &
   return true;
 }
 
-void CWsDeployFileInfo::initFileInfo(bool createOrOverwrite)
+void CWsDeployFileInfo::initFileInfo(bool createOrOverwrite, bool bClearEnv)
 {
   StringBuffer xpath;
   m_skipEnvUpdateFromNotification = false;
@@ -6127,7 +6294,8 @@ void CWsDeployFileInfo::initFileInfo(bool createOrOverwrite)
   if (!fileExists)
     toXML(pEnvRoot, sbxml.clear());
 
-  m_Environment.clear();
+  if ( bClearEnv == true )
+    m_Environment.clear();
 
   if (m_constEnvRdOnly.get() == NULL)
   {

+ 4 - 1
esp/services/WsDeploy/WsDeployService.hpp

@@ -420,7 +420,7 @@ public:
         m_envFile.clear().append(pEnvFile);
     }
     ~CWsDeployFileInfo();
-    void initFileInfo(bool createFile);
+    void initFileInfo(bool createFile, bool bClearEnv = true);
     void setConfigChanged(bool b)
     {
       m_configChanged = b;
@@ -455,6 +455,7 @@ public:
        
       return m_pFile->queryFilename();
     };
+    static void setFilePath(StringBuffer &filePath, const char* targetName);
     virtual void updateConfigFromFile();
     virtual bool deploy(IEspContext &context, IEspDeployRequest &req, IEspDeployResponse &resp);
     virtual bool graph(IEspContext &context, IEspEmptyRequest& req, IEspGraphResponse& resp);
@@ -472,6 +473,8 @@ public:
     virtual bool handleRoxieOperation(IEspContext &context, IEspHandleRoxieOperationRequest &req, IEspHandleRoxieOperationResponse &resp);
     virtual bool handleThorTopology(IEspContext &context, IEspHandleThorTopologyRequest &req, IEspHandleThorTopologyResponse &resp);
     virtual bool handleComponent(IEspContext &context, IEspHandleComponentRequest &req, IEspHandleComponentResponse &resp);
+    virtual bool handleComponentCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot);
+    virtual bool handleHardwareCopy(IPropertyTree *pComponents, IPropertyTree *pEnvRoot);
     virtual bool handleInstance(IEspContext &context, IEspHandleInstanceRequest &req, IEspHandleInstanceResponse &resp);
     virtual bool handleEspServiceBindings(IEspContext &context, IEspHandleEspServiceBindingsRequest &req, IEspHandleEspServiceBindingsResponse &resp);
     virtual bool handleComputer(IEspContext &context, IEspHandleComputerRequest &req, IEspHandleComputerResponse &resp);