Updated Branches:
  refs/heads/4.2 999c1bc1c -> 8edaf63c4

CLOUDSTACK-4850
[UCS] using template instead of cloning profile


Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/8edaf63c
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/8edaf63c
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/8edaf63c

Branch: refs/heads/4.2
Commit: 8edaf63c4e4a054b17a2dfe4233d103fb2ee9e6a
Parents: 999c1bc
Author: Frank.Zhang <frank.zh...@citrix.com>
Authored: Thu Oct 10 14:45:03 2013 -0700
Committer: Frank.Zhang <frank.zh...@citrix.com>
Committed: Thu Oct 10 14:45:03 2013 -0700

----------------------------------------------------------------------
 api/src/com/cloud/event/EventTypes.java         |   2 +
 .../org/apache/cloudstack/api/ApiConstants.java |   3 +
 client/tomcatconf/commands.properties.in        |   3 +
 .../src/com/cloud/ucs/manager/UcsCommands.java  |  85 +++++----
 .../com/cloud/ucs/manager/UcsHttpClient.java    |  61 ++++++-
 .../src/com/cloud/ucs/manager/UcsManager.java   |  19 +-
 .../com/cloud/ucs/manager/UcsManagerImpl.java   | 173 +++++++++++++++----
 .../com/cloud/ucs/structure/UcsTemplate.java    |  40 +++++
 .../api/DisassociateUcsProfileCmd.java          |  21 ++-
 ...ntiateUcsTemplateAndAssociateToBladeCmd.java |  99 +++++++++++
 .../cloudstack/api/ListUcsTemplatesCmd.java     |  55 ++++++
 .../cloudstack/api/RefreshUcsBladesCmd.java     |  71 ++++++++
 .../api/response/UcsTemplateResponse.java       |  36 ++++
 13 files changed, 588 insertions(+), 80 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java 
b/api/src/com/cloud/event/EventTypes.java
index dc20400..1f5b5b7 100755
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -443,7 +443,9 @@ public class EventTypes {
     public static final String EVENT_CLEANUP_VM_RESERVATION = 
"VM.RESERVATION.CLEANUP";
     
     public static final String EVENT_UCS_ASSOCIATED_PROFILE = 
"UCS.ASSOCIATEPROFILE";
+    public static final String EVENT_UCS_INSTANTIATE_TEMPLATE_AND_ASSOCIATE = 
"UCS.TEMPLATEASSOCIATION";
     public static final String EVENT_UCS_DISASSOCIATED_PROFILE = 
"UCS.DISASSOCIATEPROFILE";
+    public static final String EVENT_UCS_REFRESH_BLADES = "UCS.REFRESHBLADES";
 
     static {
 

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/api/src/org/apache/cloudstack/api/ApiConstants.java
----------------------------------------------------------------------
diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java 
b/api/src/org/apache/cloudstack/api/ApiConstants.java
index 14e1c96..d71db40 100755
--- a/api/src/org/apache/cloudstack/api/ApiConstants.java
+++ b/api/src/org/apache/cloudstack/api/ApiConstants.java
@@ -493,8 +493,11 @@ public class ApiConstants {
     public static final String RESERVED_IP_RANGE = "reservediprange";
     public static final String UCS_MANAGER_ID = "ucsmanagerid";
     public static final String UCS_PROFILE_DN = "profiledn";
+    public static final String UCS_TEMPLATE_DN = "templatedn";
     public static final String UCS_BLADE_DN = "bladedn";
     public static final String UCS_BLADE_ID = "bladeid";
+    public static final String UCS_PROFILE_NAME = "profilename";
+    public static final String UCS_DELETE_PROFILE = "deleteprofile";
     public static final String VM_GUEST_IP = "vmguestip";
     public static final String HEALTHCHECK_RESPONSE_TIMEOUT = 
"responsetimeout";
     public static final String HEALTHCHECK_INTERVAL_TIME = "intervaltime";

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/client/tomcatconf/commands.properties.in
----------------------------------------------------------------------
diff --git a/client/tomcatconf/commands.properties.in 
b/client/tomcatconf/commands.properties.in
index 492661e..d4aff29 100644
--- a/client/tomcatconf/commands.properties.in
+++ b/client/tomcatconf/commands.properties.in
@@ -616,9 +616,12 @@ addUcsManager=1
 listUcsManagers=1
 listUcsProfiles=1
 listUcsBlades=1
+listUcsTemplates=1
 associateUcsProfileToBlade=1
 deleteUcsManager=1
 disassociateUcsProfileFromBlade=1
+refreshUcsBlades=1
+instantiateUcsTemplateAndAssocaciateToBlade=1
 
 #### New Load Balancer commands
 createLoadBalancer=15

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java 
b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java
index 52e5edf..8232844 100755
--- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java
+++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsCommands.java
@@ -50,6 +50,27 @@ public class UcsCommands {
         return cmd.dump();
     }
 
+    public static String listTemplates(String cookie) {
+        XmlObject cmd = new XmlObject("configResolveClass");
+        cmd.putElement("cookie", cookie);
+        cmd.putElement("inHierarchical", "false");
+        cmd.putElement("classId", "lsServer");
+        cmd.putElement("inFilter", new XmlObject("inFilter")
+                .putElement("eq", new XmlObject("eq")
+                        .putElement("class", 
"lsServer").putElement("property", "type").putElement("value", 
"initial-template")));
+        return cmd.dump();
+    }
+
+    public static String instantiateTemplate(String cookie, String dn, String 
name) {
+        XmlObject cmd = new XmlObject("lsInstantiateTemplate");
+        cmd.putElement("dn",dn);
+        cmd.putElement("cookie", cookie);
+        cmd.putElement("inTargetOrg", "org-root");
+        cmd.putElement("inServerName", name);
+        cmd.putElement("inHierarchical", "no");
+        return cmd.toString();
+    }
+
     public static String cloneProfile(String cookie, String srcDn, String 
newProfileName) {
         XmlObject cmd = new XmlObject("lsClone");
         cmd.putElement("cookie", cookie);
@@ -93,38 +114,38 @@ public class UcsCommands {
     public static String associateProfileToBlade(String cookie, String 
profileDn, String bladeDn) {
         XmlObject cmd = new XmlObject("configConfMos").putElement("cookie", 
cookie).putElement("inHierarchical", "true").putElement(
                 "inConfigs", new XmlObject("inConfigs").putElement(
-                        "pair", new XmlObject("pair").putElement("key", 
profileDn).putElement(
-                                "lsServer", new XmlObject("lsServer")
-                                .putElement("agentPolicyName", "")
-                                .putElement("biosProfileName", "")
-                                .putElement("bootPolicyName", "")
-                                .putElement("descr", "")
-                                .putElement("dn", profileDn)
-                                .putElement("dynamicConPolicyName", "")
-                                .putElement("extIPState", "none")
-                                .putElement("hostFwPolicyName", "")
-                                .putElement("identPoolName", "")
-                                .putElement("localDiskPolicyName", "")
-                                .putElement("maintPolicyName", "")
-                                .putElement("mgmtAccessPolicyName", "")
-                                .putElement("mgmtFwPolicyName", "")
-                                .putElement("powerPolicyName", "")
-                                .putElement("scrubPolicyName", "")
-                                .putElement("solPolicyName", "")
-                                .putElement("srcTemplName", "")
-                                .putElement("statsPolicyName", "default")
-                                .putElement("status", "")
-                                .putElement("usrLbl", "")
-                                .putElement("uuid", "")
-                                .putElement("vconProfileName", "")
-                                .putElement("lsBinding", new 
XmlObject("lsBinding")
-                                        .putElement("pnDn", bladeDn)
-                                        .putElement("restrictMigration", "no")
-                                        .putElement("rn", "pn")
-                                )
-                                )
-                        )
-                );
+                "pair", new XmlObject("pair").putElement("key", 
profileDn).putElement(
+                "lsServer", new XmlObject("lsServer")
+                .putElement("agentPolicyName", "")
+                .putElement("biosProfileName", "")
+                .putElement("bootPolicyName", "")
+                .putElement("descr", "")
+                .putElement("dn", profileDn)
+                .putElement("dynamicConPolicyName", "")
+                .putElement("extIPState", "none")
+                .putElement("hostFwPolicyName", "")
+                .putElement("identPoolName", "")
+                .putElement("localDiskPolicyName", "")
+                .putElement("maintPolicyName", "")
+                .putElement("mgmtAccessPolicyName", "")
+                .putElement("mgmtFwPolicyName", "")
+                .putElement("powerPolicyName", "")
+                .putElement("scrubPolicyName", "")
+                .putElement("solPolicyName", "")
+                .putElement("srcTemplName", "")
+                .putElement("statsPolicyName", "default")
+                .putElement("status", "")
+                .putElement("usrLbl", "")
+                .putElement("uuid", "")
+                .putElement("vconProfileName", "")
+                .putElement("lsBinding", new XmlObject("lsBinding")
+                        .putElement("pnDn", bladeDn)
+                        .putElement("restrictMigration", "no")
+                        .putElement("rn", "pn")
+                )
+        )
+        )
+        );
 
         return cmd.dump();
     }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java 
b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java
index 7758c4c..d3dd483 100755
--- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java
+++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsHttpClient.java
@@ -17,24 +17,31 @@
 //
 package com.cloud.ucs.manager;
 
-import org.apache.commons.httpclient.Header;
-import org.apache.commons.httpclient.HttpClient;
-import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
-import org.apache.commons.httpclient.URI;
 import org.apache.commons.httpclient.contrib.ssl.EasySSLProtocolSocketFactory;
 import org.apache.commons.httpclient.methods.PostMethod;
 import org.apache.commons.httpclient.methods.StringRequestEntity;
 import org.apache.commons.httpclient.protocol.Protocol;
 
 import com.cloud.utils.exception.CloudRuntimeException;
+import org.apache.log4j.Logger;
+import org.springframework.http.*;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.client.RestTemplate;
+
+import java.net.URI;
+import java.net.URISyntaxException;
 
 public class UcsHttpClient {
-    private static HttpClient client;
+    private static final Logger logger = Logger.getLogger(UcsHttpClient.class);
+    //private static HttpClient client;
     private static Protocol ucsHttpsProtocol = new 
org.apache.commons.httpclient.protocol.Protocol("https", new 
EasySSLProtocolSocketFactory(), 443);
     private final String url;
+    private static RestTemplate template;
 
     static {
-        client = new HttpClient();
+        //client = new HttpClient();
+        template = new RestTemplate();
     }
 
     public UcsHttpClient(String ip) {
@@ -42,7 +49,46 @@ public class UcsHttpClient {
         Protocol.registerProtocol("https", ucsHttpsProtocol);
     }
 
-    public String call(String xml) {
+
+    private String call(URI uri, String body) {
+        HttpHeaders requestHeaders = new HttpHeaders();
+        requestHeaders.setContentType(MediaType.APPLICATION_XML);
+        requestHeaders.setContentLength(body.length());
+        HttpEntity<String> req = new HttpEntity<String>(body, requestHeaders);
+        logger.debug(String.format("UCS call: %s", body));
+        ResponseEntity<String> rsp = template.exchange(uri, HttpMethod.POST, 
req, String.class);
+        if (rsp.getStatusCode() == org.springframework.http.HttpStatus.OK) {
+            return rsp.getBody();
+        } else if (rsp.getStatusCode().value() == 302) {
+            // Handle HTTPS redirect
+            // Ideal way might be to configure from add manager API
+            // for using either HTTP / HTTPS
+            // Allow only one level of redirect
+            java.net.URI location = rsp.getHeaders().getLocation();
+            if (location == null) {
+                throw new CloudRuntimeException("Call failed: Bad redirect 
from UCS Manager");
+            }
+            call(location, body);
+        }
+        if (rsp.getStatusCode() != org.springframework.http.HttpStatus.OK) {
+            String err = String.format("http status: %s, response body:%s", 
rsp.getStatusCode().toString(), rsp.getBody());
+            throw new CloudRuntimeException(String.format("UCS API call 
failed, details: %s\n", err));
+        }
+
+        if (rsp.getBody().contains("errorCode")) {
+            String err = String.format("ucs call failed:\nsubmitted 
doc:%s\nresponse:%s\n", body, rsp.getBody());
+            throw new CloudRuntimeException(err);
+        }
+        return rsp.getBody();
+    }
+
+    public String call(String body) {
+        try {
+            return call(new URI(url), body);
+        } catch (URISyntaxException e) {
+            throw new CloudRuntimeException(e);
+        }
+        /*
         PostMethod post = new PostMethod(url);
         post.setRequestEntity(new StringRequestEntity(xml));
         post.setRequestHeader("Content-type", "text/xml");
@@ -80,5 +126,6 @@ public class UcsHttpClient {
         } finally {
             post.releaseConnection();
         }
+        */
     }
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java 
b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java
index babec3a..0cd695c 100755
--- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java
+++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManager.java
@@ -17,15 +17,8 @@
 //
 package com.cloud.ucs.manager;
 
-import org.apache.cloudstack.api.AddUcsManagerCmd;
-import org.apache.cloudstack.api.AssociateUcsProfileToBladeCmd;
-import org.apache.cloudstack.api.ListUcsBladeCmd;
-import org.apache.cloudstack.api.ListUcsManagerCmd;
-import org.apache.cloudstack.api.ListUcsProfileCmd;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.UcsBladeResponse;
-import org.apache.cloudstack.api.response.UcsManagerResponse;
-import org.apache.cloudstack.api.response.UcsProfileResponse;
+import org.apache.cloudstack.api.*;
+import org.apache.cloudstack.api.response.*;
 
 import com.cloud.utils.component.Manager;
 import com.cloud.utils.component.PluggableService;
@@ -35,13 +28,19 @@ public interface UcsManager extends Manager, 
PluggableService {
 
     ListResponse<UcsProfileResponse> listUcsProfiles(ListUcsProfileCmd cmd);
 
+    ListResponse<UcsTemplateResponse> listUcsTemplates(ListUcsTemplatesCmd 
cmd);
+
     ListResponse<UcsManagerResponse> listUcsManager(ListUcsManagerCmd cmd);
 
     UcsBladeResponse associateProfileToBlade(AssociateUcsProfileToBladeCmd 
cmd);
 
+    UcsBladeResponse 
instantiateTemplateAndAssociateToBlade(InstantiateUcsTemplateAndAssociateToBladeCmd
 cmd);
+
     ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd);
     
     void deleteUcsManager(Long id);
 
-    UcsBladeResponse disassociateProfile(Long bladeId);
+    ListResponse<UcsBladeResponse> refreshBlades(Long mgrId);
+
+    UcsBladeResponse disassociateProfile(DisassociateUcsProfileCmd cmd);
 }

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java 
b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java
index 4000e98..68c05f7 100755
--- a/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java
+++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/manager/UcsManagerImpl.java
@@ -30,11 +30,9 @@ import javax.ejb.Local;
 import javax.inject.Inject;
 import javax.naming.ConfigurationException;
 
+import com.cloud.ucs.structure.UcsTemplate;
 import org.apache.cloudstack.api.*;
-import org.apache.cloudstack.api.response.ListResponse;
-import org.apache.cloudstack.api.response.UcsBladeResponse;
-import org.apache.cloudstack.api.response.UcsManagerResponse;
-import org.apache.cloudstack.api.response.UcsProfileResponse;
+import org.apache.cloudstack.api.response.*;
 import org.apache.log4j.Logger;
 
 import com.cloud.configuration.Config;
@@ -198,6 +196,9 @@ public class UcsManagerImpl implements UcsManager {
             vo.setDn(b.getDn());
             vo.setUcsManagerId(ucsMgrVo.getId());
             vo.setUuid(UUID.randomUUID().toString());
+            if (!"".equals(b.getAssignedToDn())) {
+                vo.setProfileDn(b.getAssignedToDn());
+            }
             bladeDao.persist(vo);
         }
     }
@@ -261,7 +262,7 @@ public class UcsManagerImpl implements UcsManager {
                     cmd = UcsCommands.refreshCmd(mgrvo.getUsername(), 
mgrvo.getPassword(), cookie);
                 }
             }
-            if(!(cmd == null)) {
+            if(cmd != null) {
                 String ret = client.call(cmd);
                 XmlObject xo = XmlObjectParser.parseFromString(ret);
                 String cookie = xo.get("outCookie");
@@ -284,21 +285,24 @@ public class UcsManagerImpl implements UcsManager {
         return ComputeBlade.fromXmString(ret);
     }
 
+    private List<UcsTemplate> getUcsTemplates(Long ucsMgrId) {
+        String cookie = getCookie(ucsMgrId);
+        UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
+        String cmd = UcsCommands.listTemplates(cookie);
+        UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
+        String res = client.call(cmd);
+        List<UcsTemplate> tmps = UcsTemplate.fromXmlString(res);
+        return tmps;
+    }
+
     private List<UcsProfile> getUcsProfiles(Long ucsMgrId) {
         String cookie = getCookie(ucsMgrId);
         UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
-        String cmd = UcsCommands.listProfiles(cookie);
+        String cmd = UcsCommands.listTemplates(cookie);
         UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
         String res = client.call(cmd);
-        List<UcsProfile> profiles = UcsProfile.fromXmlString(res);
-        List<UcsProfile> unassociated = new ArrayList<UcsProfile>();
-        for (UcsProfile p : profiles) {
-            if (isProfileAssociated(mgrvo.getId(), p.getDn())) {
-                continue;
-            }
-            unassociated.add(p);
-        }
-        return unassociated;
+        List<UcsTemplate> tmps = UcsTemplate.fromXmlString(res);
+        return null;
     }
 
     @Override
@@ -316,6 +320,21 @@ public class UcsManagerImpl implements UcsManager {
         return response;
     }
 
+    @Override
+    public ListResponse<UcsTemplateResponse> 
listUcsTemplates(ListUcsTemplatesCmd cmd) {
+        List<UcsTemplate> templates = getUcsTemplates(cmd.getUcsManagerId());
+        ListResponse<UcsTemplateResponse> response = new 
ListResponse<UcsTemplateResponse>();
+        List<UcsTemplateResponse> rs = new ArrayList<UcsTemplateResponse>();
+        for (UcsTemplate t : templates) {
+            UcsTemplateResponse r = new UcsTemplateResponse();
+            r.setObjectName("ucstemplate");
+            r.setDn(t.getDn());
+            rs.add(r);
+        }
+        response.setResponses(rs);
+        return response;
+    }
+
     private String cloneProfile(Long ucsMgrId, String srcDn, String 
newProfileName) {
         UcsManagerVO mgrvo = ucsDao.findById(ucsMgrId);
         UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
@@ -350,8 +369,9 @@ public class UcsManagerImpl implements UcsManager {
         if (xo.get("outConfig.computeBlade.association").equals("none")) {
             throw new CloudRuntimeException(String.format("cannot associated a 
profile to blade[dn:%s]. please check your UCS manasger for detailed error 
information", dn));
         }
-        
-        return 
xo.get("outConfig.computeBlade.association").equals("associated");
+
+        return xo.get("outConfig.lsServer.assocState").equals("associated");
+        //return !xo.get("outConfig.computeBlade.assignedToDn").equals("");
     }
 
     @Override
@@ -403,6 +423,63 @@ public class UcsManagerImpl implements UcsManager {
         return rsp;
     }
 
+    @Override
+    public UcsBladeResponse 
instantiateTemplateAndAssociateToBlade(InstantiateUcsTemplateAndAssociateToBladeCmd
 cmd) {
+        String profileName = cmd.getProfileName();
+        if (profileName == null || "".equals(profileName)) {
+            profileName = UUID.randomUUID().toString().replace("-", "");
+        }
+
+        SearchCriteriaService<UcsBladeVO, UcsBladeVO> q = 
SearchCriteria2.create(UcsBladeVO.class);
+        q.addAnd(q.getEntity().getUcsManagerId(), Op.EQ, 
cmd.getUcsManagerId());
+        q.addAnd(q.getEntity().getId(), Op.EQ, cmd.getBladeId());
+        UcsBladeVO bvo = q.find();
+        if (bvo == null) {
+            throw new IllegalArgumentException(String.format("cannot find UCS 
blade[id:%s, ucs manager id:%s]", cmd.getBladeId(), cmd.getUcsManagerId()));
+        }
+
+        if (bvo.getHostId() != null) {
+            throw new CloudRuntimeException(String.format("blade[id:%s,  
dn:%s] has been associated with host[id:%s]", bvo.getId(), bvo.getDn(), 
bvo.getHostId()));
+        }
+
+        UcsManagerVO mgrvo = ucsDao.findById(cmd.getUcsManagerId());
+        String cookie = getCookie(cmd.getUcsManagerId());
+        String instantiateTemplateCmd = 
UcsCommands.instantiateTemplate(cookie, cmd.getTemplateDn(), profileName);
+        UcsHttpClient http = new UcsHttpClient(mgrvo.getUrl());
+        String res = http.call(instantiateTemplateCmd);
+        XmlObject xo = XmlObjectParser.parseFromString(res);
+        String profileDn = xo.get("outConfig.lsServer.dn");
+        String ucscmd = UcsCommands.associateProfileToBlade(cookie, profileDn, 
bvo.getDn());
+        res = http.call(ucscmd);
+        int count = 0;
+        int timeout = 3600;
+        while (count < timeout) {
+            if (isBladeAssociated(mgrvo.getId(), bvo.getDn())) {
+                break;
+            }
+
+            try {
+                TimeUnit.SECONDS.sleep(2);
+            } catch (InterruptedException e) {
+                throw new CloudRuntimeException(e);
+            }
+
+            count += 2;
+        }
+
+        if (count >= timeout) {
+            throw new CloudRuntimeException(String.format("associating 
profile[%s] to balde[%s] timeout after 600 seconds", profileDn, bvo.getDn()));
+        }
+
+        bvo.setProfileDn(profileDn);
+        bladeDao.update(bvo.getId(), bvo);
+
+        UcsBladeResponse rsp = bladeVOToResponse(bvo);
+
+        s_logger.debug(String.format("successfully associated profile[%s] to 
blade[%s]", profileDn, bvo.getDn()));
+        return rsp;
+    }
+
     private String hostIdToUuid(Long hostId) {
         if (hostId == null) {
             return null;
@@ -465,19 +542,18 @@ public class UcsManagerImpl implements UcsManager {
         rsp.setUcsManagerId(ucsManagerIdToUuid(vo.getUcsManagerId()));
         return rsp;
     }
-    
-    @Override
-    public ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd) {
+
+    private ListResponse<UcsBladeResponse> listUcsBlades(long mgrId) {
         SearchCriteriaService<UcsBladeVO, UcsBladeVO> serv = 
SearchCriteria2.create(UcsBladeVO.class);
-        serv.addAnd(serv.getEntity().getUcsManagerId(), Op.EQ, 
cmd.getUcsManagerId());
+        serv.addAnd(serv.getEntity().getUcsManagerId(), Op.EQ, mgrId);
         List<UcsBladeVO> vos = serv.list();
-        
+
         List<UcsBladeResponse> rsps = new 
ArrayList<UcsBladeResponse>(vos.size());
         for (UcsBladeVO vo : vos) {
             UcsBladeResponse rsp = bladeVOToResponse(vo);
             rsps.add(rsp);
         }
-        
+
         ListResponse<UcsBladeResponse> response = new 
ListResponse<UcsBladeResponse>();
         response.setResponses(rsps);
 
@@ -485,6 +561,11 @@ public class UcsManagerImpl implements UcsManager {
     }
 
     @Override
+    public ListResponse<UcsBladeResponse> listUcsBlades(ListUcsBladeCmd cmd) {
+        return listUcsBlades(cmd.getUcsManagerId());
+    }
+
+    @Override
     public void setName(String name) {
         this.name = name;
     }
@@ -519,6 +600,9 @@ public class UcsManagerImpl implements UcsManager {
         cmds.add(AssociateUcsProfileToBladeCmd.class);
         cmds.add(DeleteUcsManagerCmd.class);
         cmds.add(DisassociateUcsProfileCmd.class);
+        cmds.add(RefreshUcsBladesCmd.class);
+        cmds.add(ListUcsTemplatesCmd.class);
+        cmds.add(InstantiateUcsTemplateAndAssociateToBladeCmd.class);
         return cmds;
     }
 
@@ -534,16 +618,45 @@ public class UcsManagerImpl implements UcsManager {
        }
 
     @Override
-    public UcsBladeResponse disassociateProfile(Long bladeId) {
-        UcsBladeVO blade = bladeDao.findById(bladeId);
+    public ListResponse<UcsBladeResponse> refreshBlades(Long mgrId) {
+        SyncBladesThread synct = new SyncBladesThread();
+        synct.run();
+
+        UcsManagerVO mgrvo = ucsDao.findById(mgrId);
+        List<ComputeBlade> blades = listBlades(mgrvo.getId());
+        for (ComputeBlade b : blades) {
+            SearchCriteria2<UcsBladeVO, UcsBladeVO> q = 
SearchCriteria2.create(UcsBladeVO.class, UcsBladeVO.class);
+            q.addAnd(q.getEntity().getDn(), Op.EQ, b.getDn());
+            UcsBladeVO vo = q.find();
+            if (vo == null) {
+                vo = new UcsBladeVO();
+                vo.setProfileDn("".equals(b.getAssignedToDn()) ? null : 
b.getAssignedToDn());
+                vo.setDn(b.getDn());
+                vo.setUuid(UUID.randomUUID().toString());
+                vo.setUcsManagerId(mgrId);
+                bladeDao.persist(vo);
+            } else {
+                vo.setProfileDn("".equals(b.getAssignedToDn()) ? null : 
b.getAssignedToDn());
+                bladeDao.update(vo.getId(), vo);
+            }
+        }
+
+        return listUcsBlades(mgrId);
+    }
+
+    @Override
+    public UcsBladeResponse disassociateProfile(DisassociateUcsProfileCmd cmd) 
{
+        UcsBladeVO blade = bladeDao.findById(cmd.getBladeId());
         UcsManagerVO mgrvo = ucsDao.findById(blade.getUcsManagerId());
         UcsHttpClient client = new UcsHttpClient(mgrvo.getUrl());
         String cookie = getCookie(mgrvo.getId());
-        String cmd = UcsCommands.disassociateProfileFromBlade(cookie, 
blade.getProfileDn());
-        client.call(cmd);
-        cmd = UcsCommands.deleteProfile(cookie, blade.getProfileDn());
-        client = new UcsHttpClient(mgrvo.getUrl());
-        client.call(cmd);
+        String call = UcsCommands.disassociateProfileFromBlade(cookie, 
blade.getProfileDn());
+        client.call(call);
+        if (cmd.isDeleteProfile()) {
+            call = UcsCommands.deleteProfile(cookie, blade.getProfileDn());
+            client = new UcsHttpClient(mgrvo.getUrl());
+            client.call(call);
+        }
         blade.setProfileDn(null);
         bladeDao.update(blade.getId(), blade);
         UcsBladeResponse rsp = bladeVOToResponse(blade);

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsTemplate.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsTemplate.java 
b/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsTemplate.java
new file mode 100644
index 0000000..e879e15
--- /dev/null
+++ b/plugins/hypervisors/ucs/src/com/cloud/ucs/structure/UcsTemplate.java
@@ -0,0 +1,40 @@
+package com.cloud.ucs.structure;
+
+import com.cloud.utils.xmlobject.XmlObject;
+import com.cloud.utils.xmlobject.XmlObjectParser;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: frank
+ * Date: 10/8/13
+ * Time: 3:01 PM
+ * To change this template use File | Settings | File Templates.
+ */
+public class UcsTemplate {
+    private String dn;
+
+    public static List<UcsTemplate> fromXmlString(String xmlstr) {
+        List<UcsTemplate> tmps = new ArrayList<UcsTemplate>();
+        XmlObject xo = XmlObjectParser.parseFromString(xmlstr);
+        List<XmlObject> xos = xo.getAsList("outConfigs.lsServer");
+        if (xos != null) {
+            for (XmlObject x : xos) {
+                UcsTemplate t = new UcsTemplate();
+                t.setDn(x.get("dn").toString());
+                tmps.add(t);
+            }
+        }
+        return tmps;
+    }
+
+    public String getDn() {
+        return dn;
+    }
+
+    public void setDn(String dn) {
+        this.dn = dn;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DisassociateUcsProfileCmd.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DisassociateUcsProfileCmd.java
 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DisassociateUcsProfileCmd.java
index ed20989..751542d 100755
--- 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DisassociateUcsProfileCmd.java
+++ 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/DisassociateUcsProfileCmd.java
@@ -27,6 +27,9 @@ public class DisassociateUcsProfileCmd extends  BaseAsyncCmd {
     @Parameter(name=ApiConstants.UCS_BLADE_ID, type=CommandType.UUID, 
entityType=UcsBladeResponse.class, description="blade id", required=true)
     private Long bladeId;
 
+    @Parameter(name=ApiConstants.UCS_DELETE_PROFILE, type=CommandType.BOOLEAN, 
description="is deleting profile after disassociating")
+    private boolean deleteProfile;
+
     @Override
     public String getEventType() {
         return EventTypes.EVENT_UCS_DISASSOCIATED_PROFILE;
@@ -37,10 +40,26 @@ public class DisassociateUcsProfileCmd extends  
BaseAsyncCmd {
         return "disassociate a profile from blade";
     }
 
+    public Long getBladeId() {
+        return bladeId;
+    }
+
+    public void setBladeId(Long bladeId) {
+        this.bladeId = bladeId;
+    }
+
+    public boolean isDeleteProfile() {
+        return deleteProfile;
+    }
+
+    public void setDeleteProfile(boolean deleteProfile) {
+        this.deleteProfile = deleteProfile;
+    }
+
     @Override
     public void execute() throws ResourceUnavailableException, 
InsufficientCapacityException, ServerApiException, 
ConcurrentOperationException, ResourceAllocationException, 
NetworkRuleConflictException {
         try {
-            UcsBladeResponse rsp = mgr.disassociateProfile(bladeId);
+            UcsBladeResponse rsp = mgr.disassociateProfile(this);
             rsp.setResponseName(getCommandName());
             this.setResponseObject(rsp);
         } catch(Exception e) {

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/InstantiateUcsTemplateAndAssociateToBladeCmd.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/InstantiateUcsTemplateAndAssociateToBladeCmd.java
 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/InstantiateUcsTemplateAndAssociateToBladeCmd.java
new file mode 100644
index 0000000..bd9a0f8
--- /dev/null
+++ 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/InstantiateUcsTemplateAndAssociateToBladeCmd.java
@@ -0,0 +1,99 @@
+package org.apache.cloudstack.api;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.*;
+import com.cloud.ucs.manager.UcsManager;
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.response.UcsBladeResponse;
+import org.apache.cloudstack.api.response.UcsManagerResponse;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: frank
+ * Date: 10/8/13
+ * Time: 3:17 PM
+ * To change this template use File | Settings | File Templates.
+ */
+@APICommand(name="instantiateUcsTemplateAndAssocaciateToBlade", 
description="create a profile of template and associate to a blade", 
responseObject=UcsBladeResponse.class)
+public class InstantiateUcsTemplateAndAssociateToBladeCmd extends BaseAsyncCmd{
+    public static final Logger s_logger = 
Logger.getLogger(InstantiateUcsTemplateAndAssociateToBladeCmd.class);
+
+    @Inject
+    private UcsManager mgr;
+
+    @Parameter(name=ApiConstants.UCS_MANAGER_ID, type= 
BaseCmd.CommandType.UUID, description="ucs manager id", 
entityType=UcsManagerResponse.class, required=true)
+    private Long ucsManagerId;
+    @Parameter(name=ApiConstants.UCS_TEMPLATE_DN, type= 
BaseCmd.CommandType.STRING, description="template dn", required=true)
+    private String templateDn;
+    @Parameter(name=ApiConstants.UCS_BLADE_ID, type= BaseCmd.CommandType.UUID, 
entityType=UcsBladeResponse.class, description="blade id", required=true)
+    private Long bladeId;
+    @Parameter(name=ApiConstants.UCS_PROFILE_NAME, type= 
BaseCmd.CommandType.STRING, description="profile name")
+    private String profileName;
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_UCS_INSTANTIATE_TEMPLATE_AND_ASSOCIATE;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "create a profile off template and associate to a blade";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, 
InsufficientCapacityException, ServerApiException, 
ConcurrentOperationException, ResourceAllocationException, 
NetworkRuleConflictException {
+        try {
+            UcsBladeResponse rsp = 
mgr.instantiateTemplateAndAssociateToBlade(this);
+            rsp.setResponseName(getCommandName());
+            this.setResponseObject(rsp);
+        } catch (Exception e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, 
e.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return "instantiateucstemplateandassociatetobladeresponse";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+
+    public Long getUcsManagerId() {
+        return ucsManagerId;
+    }
+
+    public void setUcsManagerId(Long ucsManagerId) {
+        this.ucsManagerId = ucsManagerId;
+    }
+
+    public String getTemplateDn() {
+        return templateDn;
+    }
+
+    public void setTemplateDn(String templateDn) {
+        this.templateDn = templateDn;
+    }
+
+    public Long getBladeId() {
+        return bladeId;
+    }
+
+    public void setBladeId(Long bladeId) {
+        this.bladeId = bladeId;
+    }
+
+    public String getProfileName() {
+        return profileName;
+    }
+
+    public void setProfileName(String profileName) {
+        this.profileName = profileName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsTemplatesCmd.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsTemplatesCmd.java
 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsTemplatesCmd.java
new file mode 100644
index 0000000..7ae1222
--- /dev/null
+++ 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/ListUcsTemplatesCmd.java
@@ -0,0 +1,55 @@
+package org.apache.cloudstack.api;
+
+import com.cloud.exception.*;
+import com.cloud.ucs.manager.UcsManager;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.UcsManagerResponse;
+import org.apache.cloudstack.api.response.UcsProfileResponse;
+import org.apache.cloudstack.api.response.UcsTemplateResponse;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: frank
+ * Date: 10/8/13
+ * Time: 3:08 PM
+ * To change this template use File | Settings | File Templates.
+ */
+@APICommand(name="listUcsTemplates", description="List templates in ucs 
manager", responseObject=UcsTemplateResponse.class)
+public class ListUcsTemplatesCmd extends BaseListCmd  {
+    public static final Logger s_logger = 
Logger.getLogger(ListUcsTemplatesCmd.class);
+
+    @Inject
+    UcsManager mgr;
+
+    @Parameter(name=ApiConstants.UCS_MANAGER_ID, type= 
BaseCmd.CommandType.UUID,  entityType=UcsManagerResponse.class, 
description="the id for the ucs manager", required=true)
+    private Long ucsManagerId;
+
+    @Override
+    public void execute() throws ResourceUnavailableException, 
InsufficientCapacityException, ServerApiException, 
ConcurrentOperationException, ResourceAllocationException, 
NetworkRuleConflictException {
+        try {
+            ListResponse<UcsTemplateResponse> response = 
mgr.listUcsTemplates(this);
+            response.setResponseName(getCommandName());
+            response.setObjectName("ucstemplate");
+            this.setResponseObject(response);
+        } catch (Exception e) {
+            s_logger.warn("Exception: ", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, 
e.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return "listucstemplatesresponse";
+    }
+
+    public Long getUcsManagerId() {
+        return ucsManagerId;
+    }
+
+    public void setUcsManagerId(Long ucsManagerId) {
+        this.ucsManagerId = ucsManagerId;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/RefreshUcsBladesCmd.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/RefreshUcsBladesCmd.java
 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/RefreshUcsBladesCmd.java
new file mode 100644
index 0000000..b7249d1
--- /dev/null
+++ 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/RefreshUcsBladesCmd.java
@@ -0,0 +1,71 @@
+package org.apache.cloudstack.api;
+
+import com.cloud.event.EventTypes;
+import com.cloud.exception.*;
+import com.cloud.ucs.manager.UcsManager;
+import com.cloud.user.Account;
+import org.apache.cloudstack.api.response.ListResponse;
+import org.apache.cloudstack.api.response.UcsBladeResponse;
+import org.apache.cloudstack.api.response.UcsManagerResponse;
+import org.apache.log4j.Logger;
+
+import javax.inject.Inject;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: frank
+ * Date: 10/3/13
+ * Time: 2:18 PM
+ * To change this template use File | Settings | File Templates.
+ */
+@APICommand(name="refreshUcsBlades", description="refresh ucs blades to sync 
with UCS manager", responseObject=UcsBladeResponse.class)
+public class RefreshUcsBladesCmd  extends BaseAsyncCmd  {
+    private static Logger s_logger = 
Logger.getLogger(RefreshUcsBladesCmd.class);
+
+    @Inject
+    private UcsManager mgr;
+
+    @Parameter(name=ApiConstants.UCS_MANAGER_ID, type= 
BaseCmd.CommandType.UUID, description="ucs manager id", 
entityType=UcsManagerResponse.class, required=true)
+    private Long ucsManagerId;
+
+    public UcsManager getMgr() {
+        return mgr;
+    }
+
+    public void setMgr(UcsManager mgr) {
+        this.mgr = mgr;
+    }
+
+    @Override
+    public String getEventType() {
+        return EventTypes.EVENT_UCS_REFRESH_BLADES;
+    }
+
+    @Override
+    public String getEventDescription() {
+        return "refresh ucs blades status to sync with UCS manager";
+    }
+
+    @Override
+    public void execute() throws ResourceUnavailableException, 
InsufficientCapacityException, ServerApiException, 
ConcurrentOperationException, ResourceAllocationException, 
NetworkRuleConflictException {
+        try {
+            ListResponse<UcsBladeResponse> response = 
mgr.refreshBlades(ucsManagerId);
+            response.setResponseName(getCommandName());
+            response.setObjectName("ucsblade");
+            this.setResponseObject(response);
+        } catch (Exception e) {
+            s_logger.warn("unhandled exception:", e);
+            throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, 
e.getMessage());
+        }
+    }
+
+    @Override
+    public String getCommandName() {
+        return "refreshucsbladesresponse";
+    }
+
+    @Override
+    public long getEntityOwnerId() {
+        return Account.ACCOUNT_ID_SYSTEM;
+    }
+}

http://git-wip-us.apache.org/repos/asf/cloudstack/blob/8edaf63c/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsTemplateResponse.java
----------------------------------------------------------------------
diff --git 
a/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsTemplateResponse.java
 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsTemplateResponse.java
new file mode 100644
index 0000000..0a31dae
--- /dev/null
+++ 
b/plugins/hypervisors/ucs/src/org/apache/cloudstack/api/response/UcsTemplateResponse.java
@@ -0,0 +1,36 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+// 
+//   http://www.apache.org/licenses/LICENSE-2.0
+// 
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+package org.apache.cloudstack.api.response;
+
+import com.cloud.serializer.Param;
+import com.google.gson.annotations.SerializedName;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseResponse;
+
+public class UcsTemplateResponse extends BaseResponse {
+    @SerializedName(ApiConstants.UCS_DN) @Param(description="ucs template dn")
+    private String dn;
+
+    public String getDn() {
+        return dn;
+    }
+
+    public void setDn(String dn) {
+        this.dn = dn;
+    }
+}

Reply via email to