diff --git a/README.md b/README.md index fdc8891d3c..777ad0c624 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ INDIGO Orchestrator ============================ -This is the orchestrator of the PaaS layer, a core component of the INDIGO project. It receives high-level deployment requests and coordinates the deployment process over the IaaS platforms or Mesos. +This is the Orchestrator of the PaaS layer, a core component of the INDIGO project. It receives high-level deployment requests and coordinates the deployment process over the IaaS platforms or Mesos. You can find the REST APIs docs [orchestrator-rest-doc] (http://indigo-dc.github.io/orchestrator/restdocs/). @@ -55,30 +55,32 @@ docker build -t indigodatacloud/orchestrator /path/to/the/docker/folder 1.3 RUNNING -------------- ### With MySQL dockerized on the same host -The orchestrator can be run in 3 steps: +The Orchestrator can be run in 3 steps: -1. Run the MySQL deployments database with the command +1. Run the MySQL deployments database with the command: ``` sudo docker run --name databaseOrchestrator -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=orchestrator -d mysql:5.7 ``` -2. Run the MySQL workflow database with the command +2. Run the MySQL workflow database with the command: ``` sudo docker run --name databaseWorkflow -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=workflow -d mysql:5.7 ``` -3. Run the orchestrator with the command +3. Run the Orchestrator with the command: + + **`IMPORTANT`**: Remember to replace `ORCHESTRATOR_URL` with the base URL which the Orchestrator is available to (it MUST be accessible for the ElasticCluster callbacks!). ``` sudo docker run --name orchestrator --link databaseWorkflow:databaseWorkflow --link databaseOrchestrator:databaseOrchestrator \ - -p 80:8080 -d indigodatacloud/orchestrator + -p 80:8080 -e ORCHESTRATOR_URL="" -d indigodatacloud/orchestrator ``` ### With external databases -The orchestrator can also be run using already deployed DBs; you just need to start it with the command +The Orchestrator can also be run using already deployed DBs; you just need to start it with the command ``` sudo docker run --name orchestrator1 -h orchestrator1 -e ORCHESTRATOR_DB_ENDPOINT=DOMAIN_NAME:PORT \ -e ORCHESTRATOR_DB_NAME=SCHEMA_NAME -e ORCHESTRATOR_DB_USER=DB_USER -e ORCHESTRATOR_DB_PWD=DB_USER_PASSWORD \ @@ -89,7 +91,7 @@ using as parameters (`DOMAIN_NAME`, `PORT`, `SCHEMA_NAME`, `DB_USER`, `DB_USER_P 1.4 CONFIGURING -------------- -Besides those used to link the orchestrator to the DBs, there are other environment variables that can be set in order to configure the orchestrator behaviour. +Besides those used to link the Orchestrator to the database, there are other environment variables that can be set in order to configure the Orchestrator behaviour. ### Configure security 1. `SECURITY_ENABLE`: if set to `true` enable AAI OAuth2 authentication and authorization diff --git a/docker/Dockerfile b/docker/Dockerfile index c27a846a2d..323ff49800 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -52,10 +52,11 @@ ENV ORCHESTRATOR_DB_ENDPOINT="databaseorchestrator:3306" \ ORCHESTRATOR_DB_NAME=orchestrator \ ORCHESTRATOR_DB_USER=root \ ORCHESTRATOR_DB_PWD=root \ + ORCHESTRATOR_URL="" \ WORKFLOW_DB_ENDPOINT="databaseworkflow:3306" \ WORKFLOW_DB_NAME=workflow \ WORKFLOW_DB_USER=root \ - WORKFLOW_DB_PWD=root + WORKFLOW_DB_PWD=root ENV IM_URL="" \ PROXY_DIR="" \ diff --git a/docker/launch.sh b/docker/launch.sh index 2e9b9875e9..0c26e2d2bc 100644 --- a/docker/launch.sh +++ b/docker/launch.sh @@ -7,6 +7,7 @@ java -jar /usr/share/java/saxon.jar -o:$JBOSS_HOME/standalone/configuration/$JBO orchestrator.DB.name=$ORCHESTRATOR_DB_NAME \ orchestrator.DB.user=$ORCHESTRATOR_DB_USER \ orchestrator.DB.pwd=$ORCHESTRATOR_DB_PWD \ + orchestrator.url=$ORCHESTRATOR_URL \ workflow.DB.endpoint=$WORKFLOW_DB_ENDPOINT \ workflow.DB.name=$WORKFLOW_DB_NAME \ workflow.DB.user=$WORKFLOW_DB_USER \ diff --git a/pom.xml b/pom.xml index 72547edf82..6ef8bb60f1 100644 --- a/pom.xml +++ b/pom.xml @@ -40,9 +40,9 @@ 2.1.0 ${project.build.directory}\generated-snippets 2.17 - 0.0.3-SNAPSHOT - 1.1.0-INDIGO2-SNAPSHOT - 0.0.1-SNAPSHOT + 0.0.3-FINAL + 1.1.0-INDIGO2-ALPHA.1 + 0.0.1-BETA.1 diff --git a/src/main/java/it/reply/orchestrator/dal/entity/Deployment.java b/src/main/java/it/reply/orchestrator/dal/entity/Deployment.java index 0051c3ca6a..a5b48615ed 100644 --- a/src/main/java/it/reply/orchestrator/dal/entity/Deployment.java +++ b/src/main/java/it/reply/orchestrator/dal/entity/Deployment.java @@ -1,5 +1,6 @@ package it.reply.orchestrator.dal.entity; +import it.reply.orchestrator.dto.CloudProviderEndpoint; import it.reply.orchestrator.enums.DeploymentProvider; import it.reply.orchestrator.enums.Status; import it.reply.orchestrator.enums.Task; @@ -52,6 +53,9 @@ public class Deployment extends AbstractResourceEntity { @Column(name = "template", columnDefinition = "LONGTEXT") private String template; + @Column(name = "cloudProviderEndpoint", columnDefinition = "TEXT") + private String cloudProviderEndpoint; + /** * The user's inputs to the template. */ @@ -192,6 +196,38 @@ public synchronized void setParameters(Map parameters) { this.unserializedParameters = null; } + /** + * + * @return . + */ + public synchronized CloudProviderEndpoint getCloudProviderEndpoint() { + + CloudProviderEndpoint cpe = null; + + if (cloudProviderEndpoint != null) { + try { + cpe = JsonUtility.deserializeJson(cloudProviderEndpoint, CloudProviderEndpoint.class); + } catch (IOException ex) { + throw new RuntimeException("Failed to deserialize CloudProviderEndpoint in JSON", ex); + } + } + return cpe; + } + + /** + * . + * + */ + public synchronized void setCloudProviderEndpoint(CloudProviderEndpoint cpe) { + if (cpe != null) { + try { + cloudProviderEndpoint = JsonUtility.serializeJson(cpe); + } catch (IOException ex) { + throw new RuntimeException("Failed to serialize CloudProviderEndpoint in JSON", ex); + } + } + } + public Map getOutputs() { return outputs; } diff --git a/src/main/java/it/reply/orchestrator/dto/CloudProvider.java b/src/main/java/it/reply/orchestrator/dto/CloudProvider.java index 40294ceb50..6af44fe4ee 100644 --- a/src/main/java/it/reply/orchestrator/dto/CloudProvider.java +++ b/src/main/java/it/reply/orchestrator/dto/CloudProvider.java @@ -1,11 +1,14 @@ package it.reply.orchestrator.dto; +import it.reply.orchestrator.dto.cmdb.Image; import it.reply.orchestrator.dto.cmdb.Provider; import it.reply.orchestrator.dto.cmdb.Service; import it.reply.orchestrator.dto.cmdb.Type; import java.io.Serializable; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; /** @@ -24,6 +27,7 @@ public class CloudProvider implements Serializable { private Provider cmdbProviderData; private Map cmdbProviderServices = new HashMap<>(); + private List cmdbProviderImages = new ArrayList<>(); public CloudProvider() { } @@ -64,9 +68,28 @@ public void setCmdbProviderServices(Map cmdbProviderServices) { this.cmdbProviderServices = cmdbProviderServices; } + public List getCmdbProviderImages() { + return cmdbProviderImages; + } + + public void setCmdbProviderImages(List cmdbProviderImages) { + this.cmdbProviderImages = cmdbProviderImages; + } + + /** + * Look for a Service in the current Provider of the given Type. + * + * @param type + * the type. + * @return the Service if found, null otherwise. + */ public Service getCmbdProviderServiceByType(Type type) { - // FIXME implement getCmbdProviderServiceByType - throw new UnsupportedOperationException("NOT IMPLEMENTED"); + for (Service service : cmdbProviderServices.values()) { + if (service.getData().getType().equals(type)) { + return service; + } + } + return null; } } diff --git a/src/main/java/it/reply/orchestrator/dto/CloudProviderEndpoint.java b/src/main/java/it/reply/orchestrator/dto/CloudProviderEndpoint.java new file mode 100644 index 0000000000..94c3699e11 --- /dev/null +++ b/src/main/java/it/reply/orchestrator/dto/CloudProviderEndpoint.java @@ -0,0 +1,55 @@ +package it.reply.orchestrator.dto; + +import java.io.Serializable; + +/** + * This class holds information to connect (and authenticate) to a CloudProvider. + * + * @author l.biava + * + */ +public class CloudProviderEndpoint implements Serializable { + + private static final long serialVersionUID = -2585914648218602033L; + + public enum IaaSType { + // @formatter:off + OPENSTACK, OPENNEBULA + // @formatter:on + } + + private String imEndpoint; + private String cpEndpoint; + private IaaSType iaasType; + + public String getImEndpoint() { + return imEndpoint; + } + + public void setImEndpoint(String imEndpoint) { + this.imEndpoint = imEndpoint; + } + + public String getCpEndpoint() { + return cpEndpoint; + } + + public void setCpEndpoint(String cpEndpoint) { + this.cpEndpoint = cpEndpoint; + } + + public IaaSType getIaasType() { + return iaasType; + } + + public void setIaasType(IaaSType iaasType) { + this.iaasType = iaasType; + } + + @Override + public String toString() { + return "CloudProviderEndpoint [imEndpoint=" + imEndpoint + ", cpEndpoint=" + cpEndpoint + + ", iaasType=" + iaasType + "]"; + } + +} diff --git a/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbHasManyList.java b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbHasManyList.java new file mode 100644 index 0000000000..252ca922a6 --- /dev/null +++ b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbHasManyList.java @@ -0,0 +1,120 @@ +package it.reply.orchestrator.dto.cmdb; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Generated; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ "total_rows", "offset", "rows" }) +public class CmdbHasManyList { + + @JsonProperty("total_rows") + private Long totalRows; + @JsonProperty("offset") + private Long offset; + @JsonProperty("rows") + private List rows = new ArrayList<>(); + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("total_rows") + public Long getTotalRows() { + return totalRows; + } + + @JsonProperty("total_rows") + public void setTotalRows(Long totalRows) { + this.totalRows = totalRows; + } + + public CmdbHasManyList withTotalRows(Long totalRows) { + this.totalRows = totalRows; + return this; + } + + @JsonProperty("offset") + public Long getOffset() { + return offset; + } + + @JsonProperty("offset") + public void setOffset(Long offset) { + this.offset = offset; + } + + public CmdbHasManyList withOffset(Long offset) { + this.offset = offset; + return this; + } + + @JsonProperty("rows") + public List getRows() { + return rows; + } + + @JsonProperty("rows") + public void setRows(List rows) { + this.rows = rows; + } + + public CmdbHasManyList withRows(List rows) { + this.rows = rows; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public CmdbHasManyList withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(totalRows).append(offset).append(rows) + .append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof CmdbHasManyList) == false) { + return false; + } + @SuppressWarnings("unchecked") + CmdbHasManyList rhs = ((CmdbHasManyList) other); + return new EqualsBuilder().append(totalRows, rhs.totalRows).append(offset, rhs.offset) + .append(rows, rhs.rows).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} \ No newline at end of file diff --git a/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImage.java b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImage.java new file mode 100644 index 0000000000..f337893788 --- /dev/null +++ b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImage.java @@ -0,0 +1,134 @@ +package it.reply.orchestrator.dto.cmdb; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Generated; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ "_id", "_rev", "type", "data" }) +public class CmdbImage { + + @JsonProperty("_id") + private String id; + @JsonProperty("_rev") + private String rev; + @JsonProperty("type") + private String type; + @JsonProperty("data") + private Image data; + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("_id") + public String getId() { + return id; + } + + @JsonProperty("_id") + public void setId(String id) { + this.id = id; + } + + public CmdbImage withId(String id) { + this.id = id; + return this; + } + + @JsonProperty("_rev") + public String getRev() { + return rev; + } + + @JsonProperty("_rev") + public void setRev(String rev) { + this.rev = rev; + } + + public CmdbImage withRev(String rev) { + this.rev = rev; + return this; + } + + @JsonProperty("type") + public String getType() { + return type; + } + + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + public CmdbImage withType(String type) { + this.type = type; + return this; + } + + @JsonProperty("data") + public Image getData() { + return data; + } + + @JsonProperty("data") + public void setData(Image data) { + this.data = data; + } + + public CmdbImage withData(Image data) { + this.data = data; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public CmdbImage withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(id).append(rev).append(type).append(data) + .append(additionalProperties).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof CmdbImage) == false) { + return false; + } + CmdbImage rhs = ((CmdbImage) other); + return new EqualsBuilder().append(id, rhs.id).append(rev, rhs.rev).append(type, rhs.type) + .append(data, rhs.data).append(additionalProperties, rhs.additionalProperties).isEquals(); + } + +} \ No newline at end of file diff --git a/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImageRow.java b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImageRow.java new file mode 100644 index 0000000000..f43c8f28ab --- /dev/null +++ b/src/main/java/it/reply/orchestrator/dto/cmdb/CmdbImageRow.java @@ -0,0 +1,75 @@ +package it.reply.orchestrator.dto.cmdb; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Generated; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ "id", "key", "value", "doc" }) +public class CmdbImageRow { + + @JsonProperty("id") + private String id; + @JsonProperty("key") + private List key = new ArrayList(); + @JsonProperty("doc") + private CmdbImage image; + + @JsonProperty("id") + public String getId() { + return id; + } + + @JsonProperty("id") + public void setId(String id) { + this.id = id; + } + + public CmdbImageRow withId(String id) { + this.id = id; + return this; + } + + @JsonProperty("key") + public List getKey() { + return key; + } + + @JsonProperty("key") + public void setKey(List key) { + this.key = key; + } + + public CmdbImageRow withKey(List key) { + this.key = key; + return this; + } + + @JsonProperty("doc") + public CmdbImage getImage() { + return image; + } + + @JsonProperty("doc") + public void setImage(CmdbImage image) { + this.image = image; + } + + public CmdbImageRow withImage(CmdbImage image) { + this.image = image; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/it/reply/orchestrator/dto/cmdb/Image.java b/src/main/java/it/reply/orchestrator/dto/cmdb/Image.java new file mode 100644 index 0000000000..9bda899c7b --- /dev/null +++ b/src/main/java/it/reply/orchestrator/dto/cmdb/Image.java @@ -0,0 +1,192 @@ +package it.reply.orchestrator.dto.cmdb; + +import com.fasterxml.jackson.annotation.JsonAnyGetter; +import com.fasterxml.jackson.annotation.JsonAnySetter; +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +import org.apache.commons.lang.builder.EqualsBuilder; +import org.apache.commons.lang.builder.HashCodeBuilder; +import org.apache.commons.lang.builder.ToStringBuilder; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.Generated; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@Generated("org.jsonschema2pojo") +@JsonPropertyOrder({ "image_id", "image_name", "architecture", "type", "distribution", "version" }) +public class Image implements Serializable { + + private static final long serialVersionUID = 6029586902515892534L; + + @JsonProperty("image_id") + private String imageId; + @JsonProperty("image_name") + private String imageName; + @JsonProperty("architecture") + private String architecture; + @JsonProperty("type") + private String type; + @JsonProperty("distribution") + private String distribution; + @JsonProperty("version") + private String version; + @JsonProperty("service") + private String service; + @JsonIgnore + private Map additionalProperties = new HashMap(); + + @JsonProperty("image_id") + public String getImageId() { + return imageId; + } + + @JsonProperty("image_id") + public void setImageId(String imageId) { + this.imageId = imageId; + } + + public Image withImageId(String imageId) { + this.imageId = imageId; + return this; + } + + @JsonProperty("image_name") + public String getImageName() { + return imageName; + } + + @JsonProperty("image_name") + public void setImageName(String imageName) { + this.imageName = imageName; + } + + public Image withImageName(String imageName) { + this.imageName = imageName; + return this; + } + + @JsonProperty("architecture") + public String getArchitecture() { + return architecture; + } + + @JsonProperty("architecture") + public void setArchitecture(String architecture) { + this.architecture = architecture; + } + + public Image withArchitecture(String architecture) { + this.architecture = architecture; + return this; + } + + @JsonProperty("type") + public String getType() { + return type; + } + + @JsonProperty("type") + public void setType(String type) { + this.type = type; + } + + public Image withType(String type) { + this.type = type; + return this; + } + + @JsonProperty("distribution") + public String getDistribution() { + return distribution; + } + + @JsonProperty("distribution") + public void setDistribution(String distribution) { + this.distribution = distribution; + } + + public Image withDistribution(String distribution) { + this.distribution = distribution; + return this; + } + + @JsonProperty("version") + public String getVersion() { + return version; + } + + @JsonProperty("version") + public void setVersion(String version) { + this.version = version; + } + + public Image withVersion(String version) { + this.version = version; + return this; + } + + @JsonProperty("service") + public String getService() { + return service; + } + + @JsonProperty("service") + public void setService(String service) { + this.service = service; + } + + public Image withService(String service) { + this.service = service; + return this; + } + + @Override + public String toString() { + return ToStringBuilder.reflectionToString(this); + } + + @JsonAnyGetter + public Map getAdditionalProperties() { + return this.additionalProperties; + } + + @JsonAnySetter + public void setAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + } + + public Image withAdditionalProperty(String name, Object value) { + this.additionalProperties.put(name, value); + return this; + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(imageId).append(imageName).append(architecture).append(type) + .append(distribution).append(version).append(service).append(additionalProperties) + .toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof Image) == false) { + return false; + } + Image rhs = ((Image) other); + return new EqualsBuilder().append(imageId, rhs.imageId).append(imageName, rhs.imageName) + .append(architecture, rhs.architecture).append(type, rhs.type) + .append(distribution, rhs.distribution).append(version, rhs.version) + .append(service, rhs.service).append(additionalProperties, rhs.additionalProperties) + .isEquals(); + } + +} \ No newline at end of file diff --git a/src/main/java/it/reply/orchestrator/dto/deployment/DeploymentMessage.java b/src/main/java/it/reply/orchestrator/dto/deployment/DeploymentMessage.java index b906f4a86e..dbfcc9aeef 100644 --- a/src/main/java/it/reply/orchestrator/dto/deployment/DeploymentMessage.java +++ b/src/main/java/it/reply/orchestrator/dto/deployment/DeploymentMessage.java @@ -2,6 +2,8 @@ import it.reply.orchestrator.dal.entity.Deployment; import it.reply.orchestrator.dal.entity.Resource; +import it.reply.orchestrator.dto.CloudProvider; +import it.reply.orchestrator.dto.CloudProviderEndpoint; import it.reply.orchestrator.enums.DeploymentProvider; import it.reply.orchestrator.service.deployment.providers.ChronosServiceImpl.IndigoJob; @@ -35,6 +37,9 @@ public class DeploymentMessage implements Serializable { private boolean pollComplete; private boolean skipPollInterval; + private CloudProvider chosenCloudProvider; + private CloudProviderEndpoint chosenCloudProviderEndpoint; + private String oauth2Token; /** @@ -115,6 +120,22 @@ public void setSkipPollInterval(boolean skipPollInterval) { this.skipPollInterval = skipPollInterval; } + public CloudProvider getChosenCloudProvider() { + return chosenCloudProvider; + } + + public void setChosenCloudProvider(CloudProvider chosenCloudProvider) { + this.chosenCloudProvider = chosenCloudProvider; + } + + public CloudProviderEndpoint getChosenCloudProviderEndpoint() { + return chosenCloudProviderEndpoint; + } + + public void setChosenCloudProviderEndpoint(CloudProviderEndpoint chosenCloudProviderEndpoint) { + this.chosenCloudProviderEndpoint = chosenCloudProviderEndpoint; + } + public String getOauth2Token() { return oauth2Token; } diff --git a/src/main/java/it/reply/orchestrator/service/CloudProviderEndpointServiceImpl.java b/src/main/java/it/reply/orchestrator/service/CloudProviderEndpointServiceImpl.java new file mode 100644 index 0000000000..a30bbe920c --- /dev/null +++ b/src/main/java/it/reply/orchestrator/service/CloudProviderEndpointServiceImpl.java @@ -0,0 +1,115 @@ +package it.reply.orchestrator.service; + +import it.reply.orchestrator.dal.entity.Deployment; +import it.reply.orchestrator.dto.CloudProviderEndpoint; +import it.reply.orchestrator.dto.CloudProviderEndpoint.IaaSType; +import it.reply.orchestrator.dto.RankCloudProvidersMessage; +import it.reply.orchestrator.dto.cmdb.Type; +import it.reply.orchestrator.dto.ranker.RankedCloudProvider; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.stereotype.Service; + +@Service +public class CloudProviderEndpointServiceImpl { + private static final Logger LOG = LogManager.getLogger(CloudProviderEndpointServiceImpl.class); + + /** + * Choose a Cloud Provider. + * + * @param deployment + * . + * @param rankCloudProvidersMessage + * . + * @return . + */ + public RankedCloudProvider chooseCloudProvider(Deployment deployment, + RankCloudProvidersMessage rankCloudProvidersMessage) { + + // TODO Check ranker errors (i.e. providers with ranked = false) + RankedCloudProvider chosenCp = null; + for (RankedCloudProvider rcp : rankCloudProvidersMessage.getRankedCloudProviders()) { + // Choose the one with lowest rank AND that matches iaasType (TEMPORARY) + if (chosenCp == null || rcp.getRank() < chosenCp.getRank()) { + chosenCp = rcp; + } + } + + if (chosenCp == null) { + String errorMsg = String.format("No Cloud Provider found for: {}", + rankCloudProvidersMessage.getRankedCloudProviders()); + LOG.error(errorMsg); + throw new IllegalArgumentException(errorMsg); + } + + LOG.debug("Selected Cloud Provider is: {}", chosenCp); + return chosenCp; + } + + /** + * . + * + * @param deployment + * . + * @param rankCloudProvidersMessage + * . + * @param chosenCp + * . + * @return . + */ + public CloudProviderEndpoint getCloudProviderEndpoint(Deployment deployment, + RankCloudProvidersMessage rankCloudProvidersMessage, RankedCloudProvider chosenCp) { + + IaaSType iaasType = getProviderIaaSType(rankCloudProvidersMessage, chosenCp.getName()); + + CloudProviderEndpoint cpe = new CloudProviderEndpoint(); + + it.reply.orchestrator.dto.cmdb.Service computeService = rankCloudProvidersMessage + .getCloudProviders().get(chosenCp.getName()).getCmbdProviderServiceByType(Type.COMPUTE); + + cpe.setCpEndpoint(computeService.getData().getEndpoint()); + cpe.setIaasType(iaasType); + // FIXME Add IM EP, if available + + return cpe; + } + + // /** + // * TEMPORARY method to decide whether it is needed to coerce CP choice based on template content + // * (i.e. currently used to force Mesos cluster deployment on OpenStack). + // * + // * @param template + // * . + // * @return . + // */ + // public IaaSType getIaaSTypeFromTosca(String template) { + // + // if (template.contains("tosca.nodes.indigo.MesosMaster")) { + // return IaaSType.OPENSTACK; + // } else { + // return IaaSType.OPENNEBULA; + // } + // } + + // protected boolean isCompatible(IaaSType requiredType, IaaSType providerType) { + // if (requiredType == providerType) { + // return true; + // } else if (providerType == IaaSType.OPENNEBULA) { + // return true; + // } else { + // return false; + // } + // } + + protected IaaSType getProviderIaaSType(RankCloudProvidersMessage rankCloudProvidersMessage, + String providerName) { + String serviceType = rankCloudProvidersMessage.getCloudProviders().get(providerName) + .getCmbdProviderServiceByType(Type.COMPUTE).getData().getServiceType(); + if (serviceType.contains("openstack")) { + return IaaSType.OPENSTACK; + } + + return IaaSType.OPENNEBULA; + } +} diff --git a/src/main/java/it/reply/orchestrator/service/CmdbService.java b/src/main/java/it/reply/orchestrator/service/CmdbService.java index 488598654c..7af81012ca 100644 --- a/src/main/java/it/reply/orchestrator/service/CmdbService.java +++ b/src/main/java/it/reply/orchestrator/service/CmdbService.java @@ -1,13 +1,32 @@ package it.reply.orchestrator.service; +import it.reply.orchestrator.dto.cmdb.CmdbImage; import it.reply.orchestrator.dto.cmdb.Provider; import it.reply.orchestrator.dto.cmdb.Service; +import java.util.List; + public interface CmdbService { public Service getServiceById(String id); public Provider getProviderById(String id); + // /** + // * Complex method to retrieve {@link Image}s with all metadata for a given provider.
+ // * Currently, it is needed to extract the correct service from the provider and the query the + // CMDB + // * to retrieve metadata of each single image (because only ID and Name are listed in the API). + // * + // * @param providerId + // * . + // * @return . + // */ + // public List getImagesByProvider(String providerId); + + public List getImagesByService(String serviceId); + + public CmdbImage getImageById(String imageId); + public String getUrl(); } diff --git a/src/main/java/it/reply/orchestrator/service/CmdbServiceImpl.java b/src/main/java/it/reply/orchestrator/service/CmdbServiceImpl.java index ff9f9be26d..0c57fe0a19 100644 --- a/src/main/java/it/reply/orchestrator/service/CmdbServiceImpl.java +++ b/src/main/java/it/reply/orchestrator/service/CmdbServiceImpl.java @@ -1,15 +1,23 @@ package it.reply.orchestrator.service; +import it.reply.orchestrator.dto.cmdb.CmdbHasManyList; +import it.reply.orchestrator.dto.cmdb.CmdbImage; +import it.reply.orchestrator.dto.cmdb.CmdbImageRow; import it.reply.orchestrator.dto.cmdb.Provider; import it.reply.orchestrator.exception.service.DeploymentException; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.PropertySource; +import org.springframework.core.ParameterizedTypeReference; +import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import java.util.List; +import java.util.stream.Collectors; + @Service @PropertySource("classpath:cmdb/cmdb.properties") public class CmdbServiceImpl implements CmdbService { @@ -54,4 +62,57 @@ public Provider getProviderById(String id) { + response.getStatusCode().toString() + " " + response.getStatusCode().getReasonPhrase()); } + @Override + public CmdbImage getImageById(String imageId) { + ResponseEntity response = + restTemplate.getForEntity(url.concat("image/id").concat(imageId), CmdbImage.class); + if (response.getStatusCode().is2xxSuccessful()) { + return response.getBody(); + } + throw new DeploymentException("Unable to find image <" + imageId + "> in the CMDB." + + response.getStatusCode().toString() + " " + response.getStatusCode().getReasonPhrase()); + } + + @Override + public List getImagesByService(String serviceId) { + ResponseEntity> response = restTemplate.exchange( + url.concat(serviceIdUrlPath).concat(serviceId).concat("/has_many/images?include_docs=true"), + HttpMethod.GET, null, new ParameterizedTypeReference>() { + }); + + if (response.getStatusCode().is2xxSuccessful()) { + return response.getBody().getRows().stream().map(e -> e.getImage()) + .collect(Collectors.toList()); + } + throw new DeploymentException("Unable to find images for service <" + serviceId + + "> in the CMDB." + response.getStatusCode().toString() + " " + + response.getStatusCode().getReasonPhrase()); + } + + // @Override + // public List getImagesAndMetadataByService(String serviceId) { + // List images = new ArrayList<>(); + // for (CmdbImage image : getImagesByService(serviceId)) { + // images.add(getImageById(image.getId())); + // } + // return images; + // } + + // @Override + // public List getImagesByProvider(String providerId) { + // + // + // providerId = "STUB:" + providerId; + // // FIXME: Stub + // return Arrays.asList( + // new Image().withImageName("indigodatacloud/ubuntu-sshd").withImageId(providerId + "/5") + // .withArchitecture("x86_64").withType("linux").withDistribution("ubuntu") + // .withVersion("14.04"), + // new Image().withImageName("linux-ubuntu-14.04").withImageId(providerId + "/5") + // .withArchitecture("x86_64").withType("linux").withDistribution("ubuntu") + // .withVersion("14.04"), + // new Image().withImageName("indigodatacloudapps/docker-galaxy") + // .withImageId(providerId + "/13")); + // } + } diff --git a/src/main/java/it/reply/orchestrator/service/DeploymentServiceImpl.java b/src/main/java/it/reply/orchestrator/service/DeploymentServiceImpl.java index 03768682db..58dddb7239 100644 --- a/src/main/java/it/reply/orchestrator/service/DeploymentServiceImpl.java +++ b/src/main/java/it/reply/orchestrator/service/DeploymentServiceImpl.java @@ -122,11 +122,7 @@ public Deployment createDeployment(DeploymentRequest request) { (isChronosDeployment ? DEPLOYMENT_TYPE_CHRONOS : DEPLOYMENT_TYPE_TOSCA)); // Build deployment message - DeploymentMessage deploymentMessage = new DeploymentMessage(); - if (oauth2TokenService.isSecurityEnabled()) { - deploymentMessage.setOauth2Token(oauth2TokenService.getOAuth2Token()); - } - deploymentMessage.setDeploymentId(deployment.getId()); + DeploymentMessage deploymentMessage = buildDeploymentMessage(deployment); deploymentMessage.setDeploymentProvider( (isChronosDeployment ? DeploymentProvider.CHRONOS : DeploymentProvider.IM)); params.put(WorkflowConstants.WF_PARAM_DEPLOYMENT_MESSAGE, deploymentMessage); @@ -145,6 +141,19 @@ public Deployment createDeployment(DeploymentRequest request) { } + protected DeploymentMessage buildDeploymentMessage(Deployment deployment) { + DeploymentMessage deploymentMessage = new DeploymentMessage(); + if (oauth2TokenService.isSecurityEnabled()) { + deploymentMessage.setOauth2Token(oauth2TokenService.getOAuth2Token()); + } + deploymentMessage.setDeploymentId(deployment.getId()); + deploymentMessage.setDeploymentProvider(deployment.getDeploymentProvider()); + deploymentMessage.setChosenCloudProviderEndpoint(deployment.getCloudProviderEndpoint()); + + return deploymentMessage; + + } + /** * Temporary method to decide whether a given deployment has to be deployed using Chronos (just * for experiments).
@@ -191,17 +200,14 @@ public void deleteDeployment(String uuid) { Map params = new HashMap<>(); params.put("DEPLOYMENT_ID", deployment.getId()); + // FIXME: if the WF fails before setting deployment.getDeploymentProvider(), we should just + // delete the failed deployment ? // FIXME: Temporary - just for test params.put(WorkflowConstants.WF_PARAM_DEPLOYMENT_TYPE, deployment.getDeploymentProvider().name()); // Build deployment message - DeploymentMessage deploymentMessage = new DeploymentMessage(); - if (oauth2TokenService.isSecurityEnabled()) { - deploymentMessage.setOauth2Token(oauth2TokenService.getOAuth2Token()); - } - deploymentMessage.setDeploymentId(deployment.getId()); - deploymentMessage.setDeploymentProvider(deployment.getDeploymentProvider()); + DeploymentMessage deploymentMessage = buildDeploymentMessage(deployment); params.put(WorkflowConstants.WF_PARAM_DEPLOYMENT_MESSAGE, deploymentMessage); ProcessInstance pi = null; @@ -256,12 +262,7 @@ public void updateDeployment(String id, DeploymentRequest request) { params.put("TOSCA_TEMPLATE", request.getTemplate()); // Build deployment message - DeploymentMessage deploymentMessage = new DeploymentMessage(); - if (oauth2TokenService.isSecurityEnabled()) { - deploymentMessage.setOauth2Token(oauth2TokenService.getOAuth2Token()); - } - deploymentMessage.setDeploymentId(deployment.getId()); - deploymentMessage.setDeploymentProvider(deployment.getDeploymentProvider()); + DeploymentMessage deploymentMessage = buildDeploymentMessage(deployment); params.put(WorkflowConstants.WF_PARAM_DEPLOYMENT_MESSAGE, deploymentMessage); ProcessInstance pi = null; diff --git a/src/main/java/it/reply/orchestrator/service/ToscaService.java b/src/main/java/it/reply/orchestrator/service/ToscaService.java index 0a964247a5..41f8a1c427 100644 --- a/src/main/java/it/reply/orchestrator/service/ToscaService.java +++ b/src/main/java/it/reply/orchestrator/service/ToscaService.java @@ -12,6 +12,7 @@ import com.sun.istack.NotNull; +import it.reply.orchestrator.dto.CloudProvider; import it.reply.orchestrator.exception.service.ToscaException; import java.io.IOException; @@ -57,7 +58,41 @@ public ParsingResult getArchiveRootFromTemplate(@Nonnull String tos public String customizeTemplate(@Nonnull String toscaTemplate, @NotNull String deploymentId) throws IOException, ToscaException; - public void addDeploymentId(ArchiveRoot parsingResult, String deploymentId); + /** + * Adds the parameters needed for 'tosca.nodes.indigo.ElasticCluster' nodes (deployment_id, + * orchestrator_url). + * + * @param parsingResult + * . + * @param deploymentId + * . + */ + public void addElasticClusterParameters(ArchiveRoot parsingResult, String deploymentId); + + /** + * Replace images data in 'tosca.capabilities.indigo.OperatingSystem' capabilities in the TOSCA + * template with the provider-specific identifier. + * + * @param parsingResult + * the in-memory TOSCA template. + * @param cloudProvider + * the chosen cloud provider data. + */ + public void contextualizeImages(ArchiveRoot parsingResult, CloudProvider cloudProvider); + + /** + * Find matches for images data in 'tosca.capabilities.indigo.OperatingSystem' capabilities in the + * TOSCA template with the provider-specific identifier. + * + * @param parsingResult + * the in-memory TOSCA template. + * @param cloudProvider + * the chosen cloud provider data. + * @param replace + * whether to actually replace the image IDs or just do a dry-run. + */ + public void contextualizeImages(ArchiveRoot parsingResult, CloudProvider cloudProvider, + boolean replace); /** * Verifies that all the template's required inputs are present in the user's input list. diff --git a/src/main/java/it/reply/orchestrator/service/ToscaServiceImpl.java b/src/main/java/it/reply/orchestrator/service/ToscaServiceImpl.java index 82ad896e31..bff53c49d1 100644 --- a/src/main/java/it/reply/orchestrator/service/ToscaServiceImpl.java +++ b/src/main/java/it/reply/orchestrator/service/ToscaServiceImpl.java @@ -24,6 +24,8 @@ import alien4cloud.tosca.serializer.VelocityUtil; import alien4cloud.utils.FileUtil; +import it.reply.orchestrator.dto.CloudProvider; +import it.reply.orchestrator.dto.cmdb.Image; import it.reply.orchestrator.exception.service.ToscaException; import org.apache.logging.log4j.LogManager; @@ -81,6 +83,8 @@ public class ToscaServiceImpl implements ToscaService { private String normativeLocalName; @Value("${tosca.definitions.indigo}") private String indigoLocalName; + @Value("${orchestrator.url}") + private String orchestratorUrl; /** * Load normative and non-normative types. @@ -183,7 +187,7 @@ public String customizeTemplate(@Nonnull String toscaTemplate, @Nonnull String d ArchiveRoot ar = parseTemplate(toscaTemplate); - addDeploymentId(ar, deploymentId); + addElasticClusterParameters(ar, deploymentId); return getTemplateFromTopology(ar); @@ -285,7 +289,173 @@ private void checkParsingErrors(List errorList) throws ToscaExcept } @Override - public void addDeploymentId(ArchiveRoot parsingResult, String deploymentId) { + public void contextualizeImages(ArchiveRoot parsingResult, CloudProvider cloudProvider) { + contextualizeImages(parsingResult, cloudProvider, true); + } + + @Override + public void contextualizeImages(ArchiveRoot parsingResult, CloudProvider cloudProvider, + boolean replace) { + try { + Map nodes = parsingResult.getTopology().getNodeTemplates(); + for (Map.Entry entry : nodes.entrySet()) { + NodeTemplate node = entry.getValue(); + // Only indigo.Compute nodes are relevant + // FIXME: Check inheritance of tosca.nodes.indigo.Compute + if (node.getType().equals("tosca.nodes.indigo.Compute")) { + Capability osCapability = null; + if (node.getCapabilities() == null + || (osCapability = node.getCapabilities().get("os")) == null) { + // The node doesn't have an OS Capability -> need to add a dummy one to hold a random + // image for underlying deployment systems + LOG.debug(String.format("Generating default OperatingSystem capability for node <%s>", + node.getName())); + if (node.getCapabilities() == null) { + node.setCapabilities(new HashMap<>()); + } + osCapability = new Capability(); + osCapability.setType("tosca.capabilities.indigo.OperatingSystem"); + node.getCapabilities().put("os", osCapability); + } + + // We've got an OS capability -> Check the attributes to find best match for the image + Image imageMetadata = new Image(); + if (osCapability.getProperties().get("image") != null) { + imageMetadata.setImageName( + (String) getCapabilityPropertyValueByName(osCapability, "image").getValue()); + } + if (osCapability.getProperties().get("architecture") != null) { + imageMetadata.setArchitecture( + (String) getCapabilityPropertyValueByName(osCapability, "architecture").getValue()); + } + if (osCapability.getProperties().get("type") != null) { + imageMetadata.setType( + (String) getCapabilityPropertyValueByName(osCapability, "type").getValue()); + } + if (osCapability.getProperties().get("distribution") != null) { + imageMetadata.setDistribution( + (String) getCapabilityPropertyValueByName(osCapability, "distribution").getValue()); + } + if (osCapability.getProperties().get("version") != null) { + imageMetadata.setVersion( + (String) getCapabilityPropertyValueByName(osCapability, "version").getValue()); + } + + Image image = getBestImageForCloudProvider(imageMetadata, cloudProvider); + + // No image match found -> throw error + if (image == null) { + LOG.error( + String.format("Failed to found a match in provider <%s> for image metadata <%s>", + cloudProvider.getId(), imageMetadata)); + throw new IllegalArgumentException( + String.format("Failed to found a match in provider <%s> for image metadata <%s>", + cloudProvider.getId(), imageMetadata)); + } + + // Found a good image -> replace the image attribute with the provider-specific ID + LOG.debug(String.format( + "Found image match in <%s> for image metadata <%s>, provider-specific image id <%s>", + cloudProvider.getId(), imageMetadata, image.getImageId())); + if (replace) { + ScalarPropertyValue scalarPropertyValue = new ScalarPropertyValue(image.getImageId()); + scalarPropertyValue.setPrintable(true); + osCapability.getProperties().put("image", scalarPropertyValue); + } + + } + } + } catch (Exception ex) { + throw new RuntimeException("Failed to contextualize images: " + ex.getMessage(), ex); + } + } + + protected Image getBestImageForCloudProvider(Image imageMetadata, CloudProvider cloudProvider) { + + // Match image name first (for INDIGO specific use case, if the image cannot be found with the + // specified name it means that a base image + Ansible configuration have to be used -> the + // base image will be chosen with the other filters and image metadata - architecture, type, + // distro, version) + if (imageMetadata.getImageName() != null) { + Image imageWithName = + findImageWithNameOnCloudProvider(imageMetadata.getImageName(), cloudProvider); + + if (imageWithName != null) { + LOG.debug("Image <{}> found with name <{}>", imageWithName.getImageId(), + imageMetadata.getImageName()); + return imageWithName; + } else { + LOG.debug("Image not found with name <{}>, trying with other fields: <{}>", + imageMetadata.getImageName(), imageMetadata); + } + } + + for (Image image : cloudProvider.getCmdbProviderImages()) { + // Match or skip image based on each additional optional attribute + if (imageMetadata.getType() != null) { + if (!imageMetadata.getType().equalsIgnoreCase(image.getType())) { + continue; + } + } + + if (imageMetadata.getArchitecture() != null) { + if (!imageMetadata.getArchitecture().equalsIgnoreCase(image.getArchitecture())) { + continue; + } + } + + if (imageMetadata.getDistribution() != null) { + if (!imageMetadata.getDistribution().equalsIgnoreCase(image.getDistribution())) { + continue; + } + } + + if (imageMetadata.getVersion() != null) { + if (!imageMetadata.getVersion().equalsIgnoreCase(image.getVersion())) { + continue; + } + } + + LOG.debug("Image <{}> found with fields: <{}>", imageMetadata.getImageId(), imageMetadata); + return image; + } + return null; + + } + + protected Image findImageWithNameOnCloudProvider(String requiredImageName, + CloudProvider cloudProvider) { + for (Image image : cloudProvider.getCmdbProviderImages()) { + if (matchImageNameAndTag(requiredImageName, image.getImageName())) { + return image; + } + } + return null; + } + + protected boolean matchImageNameAndTag(String requiredImageName, String availableImageName) { + // Extract Docker tag if available + String[] requiredImageNameSplit = requiredImageName.split(":"); + String requiredImageBaseName = requiredImageNameSplit[0]; + String requiredImageTag = + (requiredImageNameSplit.length > 1 ? requiredImageNameSplit[1] : null); + + String[] availableImageNameSplit = availableImageName.split(":"); + String availableImageBaseName = availableImageNameSplit[0]; + String availableImageTag = + (availableImageNameSplit.length > 1 ? availableImageNameSplit[1] : null); + + // Match name + boolean nameMatch = requiredImageBaseName.equals(availableImageBaseName); + // Match tag (if not given the match is true) + boolean tagMatch = + (requiredImageTag != null ? requiredImageTag.equals(availableImageTag) : true); + + return nameMatch && tagMatch; + } + + @Override + public void addElasticClusterParameters(ArchiveRoot parsingResult, String deploymentId) { Map nodes = parsingResult.getTopology().getNodeTemplates(); for (Map.Entry entry : nodes.entrySet()) { if (entry.getValue().getType().equals("tosca.nodes.indigo.ElasticCluster")) { @@ -293,6 +463,10 @@ public void addDeploymentId(ArchiveRoot parsingResult, String deploymentId) { ScalarPropertyValue scalarPropertyValue = new ScalarPropertyValue(deploymentId); scalarPropertyValue.setPrintable(true); entry.getValue().getProperties().put("deployment_id", scalarPropertyValue); + // Create new property with the orchestrator_url and set as printable + scalarPropertyValue = new ScalarPropertyValue(orchestratorUrl); + scalarPropertyValue.setPrintable(true); + entry.getValue().getProperties().put("orchestrator_url", scalarPropertyValue); } } } diff --git a/src/main/java/it/reply/orchestrator/service/commands/BaseRankCloudProvidersCommand.java b/src/main/java/it/reply/orchestrator/service/commands/BaseRankCloudProvidersCommand.java index a3ac564a31..6c79996412 100644 --- a/src/main/java/it/reply/orchestrator/service/commands/BaseRankCloudProvidersCommand.java +++ b/src/main/java/it/reply/orchestrator/service/commands/BaseRankCloudProvidersCommand.java @@ -60,6 +60,6 @@ protected ExecutionResults customExecute(CommandContext ctx) throws Exception { } protected abstract RankCloudProvidersMessage - customExecute(RankCloudProvidersMessage rankCloudProvidersMessage); + customExecute(RankCloudProvidersMessage rankCloudProvidersMessage) throws Exception; } diff --git a/src/main/java/it/reply/orchestrator/service/commands/GetCmdbData.java b/src/main/java/it/reply/orchestrator/service/commands/GetCmdbData.java index f1395c8ae3..9497c4719f 100644 --- a/src/main/java/it/reply/orchestrator/service/commands/GetCmdbData.java +++ b/src/main/java/it/reply/orchestrator/service/commands/GetCmdbData.java @@ -3,22 +3,28 @@ import it.reply.orchestrator.dto.CloudProvider; import it.reply.orchestrator.dto.RankCloudProvidersMessage; import it.reply.orchestrator.dto.cmdb.Service; +import it.reply.orchestrator.dto.cmdb.Type; import it.reply.orchestrator.service.CmdbService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.Map; +import java.util.stream.Collectors; @Component public class GetCmdbData extends BaseRankCloudProvidersCommand { + private static final Logger LOG = LogManager.getLogger(GetCmdbData.class); + @Autowired private CmdbService cmdbService; @Override - protected RankCloudProvidersMessage customExecute( - RankCloudProvidersMessage rankCloudProvidersMessage) { + protected RankCloudProvidersMessage + customExecute(RankCloudProvidersMessage rankCloudProvidersMessage) { // Get CMDB data for each Cloud Provider for (Map.Entry providerEntry : rankCloudProvidersMessage @@ -34,7 +40,20 @@ protected RankCloudProvidersMessage customExecute( serviceEntry.setValue(cmdbService.getServiceById(serviceEntry.getKey())); } - // TODO Get other data (i.e. OneData, Images mapping, etc) + // FIXME Get other data (i.e. OneData, Images mapping, etc) + + // Get images for provider (requires to know the compute service) + // FIXME: What if there are multiple compute service for a provider (remember that those are + // SLAM given)? + Service imageService = cp.getCmbdProviderServiceByType(Type.COMPUTE); + if (imageService != null) { + LOG.debug("Retrieving image list for service <{}> of provider <{}>", imageService.getId(), + cp.getId()); + cp.setCmdbProviderImages(cmdbService.getImagesByService(imageService.getId()).stream() + .map(e -> e.getData()).collect(Collectors.toList())); + } else { + LOG.debug("No image service to retrieve image list from for provider <{}>", cp.getId()); + } } return rankCloudProvidersMessage; diff --git a/src/main/java/it/reply/orchestrator/service/commands/PrefilterCloudProviders.java b/src/main/java/it/reply/orchestrator/service/commands/PrefilterCloudProviders.java index 093c477422..421e4fdf08 100644 --- a/src/main/java/it/reply/orchestrator/service/commands/PrefilterCloudProviders.java +++ b/src/main/java/it/reply/orchestrator/service/commands/PrefilterCloudProviders.java @@ -1,16 +1,102 @@ package it.reply.orchestrator.service.commands; +import alien4cloud.tosca.model.ArchiveRoot; + +import it.reply.orchestrator.dal.entity.Deployment; +import it.reply.orchestrator.dal.repository.DeploymentRepository; +import it.reply.orchestrator.dto.CloudProvider; import it.reply.orchestrator.dto.RankCloudProvidersMessage; +import it.reply.orchestrator.dto.slam.Preference; +import it.reply.orchestrator.dto.slam.PreferenceCustomer; +import it.reply.orchestrator.dto.slam.Priority; +import it.reply.orchestrator.dto.slam.Sla; +import it.reply.orchestrator.service.ToscaService; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + @Component public class PrefilterCloudProviders extends BaseRankCloudProvidersCommand { + private static final Logger LOG = LogManager.getLogger(PrefilterCloudProviders.class); + + @Autowired + private DeploymentRepository deploymentRepository; + + @Autowired + private ToscaService toscaService; + @Override protected RankCloudProvidersMessage - customExecute(RankCloudProvidersMessage rankCloudProvidersMessage) { + customExecute(RankCloudProvidersMessage rankCloudProvidersMessage) throws Exception { // TODO Filter cloud providers (i.e. based on OneData) + + Deployment deployment = + deploymentRepository.findOne(rankCloudProvidersMessage.getDeploymentId()); + + // Filter out providers that do not support the requested images + ArchiveRoot ar = toscaService.parseTemplate(deployment.getTemplate()); + Iterator> it = + rankCloudProvidersMessage.getCloudProviders().entrySet().iterator(); + List providersToDiscard = new ArrayList<>(); + List servicesToDiscard = new ArrayList<>(); + while (it.hasNext()) { + Map.Entry entry = it.next(); + try { + toscaService.contextualizeImages(ar, entry.getValue(), false); + } catch (Exception ex) { + // Failed to match all required images -> discard provider + LOG.debug("Discarded provider {} because it doesn't match images requirements" + + " for deployment {}: {}", entry.getKey(), deployment.getId(), ex.getMessage()); + providersToDiscard.add(entry.getKey()); + servicesToDiscard.addAll(entry.getValue().getCmdbProviderServices().keySet()); + it.remove(); + } + + } + + // Remove discarded provider from SLAs and Preferences + for (String providerName : providersToDiscard) { + Iterator slaIt = rankCloudProvidersMessage.getSlamPreferences().getSla().iterator(); + while (slaIt.hasNext()) { + if (providerName.equals(slaIt.next().getProvider())) { + slaIt.remove(); + } + } + } + + for (String serviceId : servicesToDiscard) { + Iterator extPrefIt = + rankCloudProvidersMessage.getSlamPreferences().getPreferences().iterator(); + while (extPrefIt.hasNext()) { + Preference extPreference = extPrefIt.next(); + Iterator intPrefIt = extPreference.getPreferences().iterator(); + while (intPrefIt.hasNext()) { + PreferenceCustomer intPreference = intPrefIt.next(); + Iterator priorityIt = intPreference.getPriority().iterator(); + while (priorityIt.hasNext()) { + if (serviceId.equals(priorityIt.next().getServiceId())) { + priorityIt.remove(); + } + } + if (intPreference.getPriority().isEmpty()) { + intPrefIt.remove(); + } + } + if (extPreference.getPreferences().isEmpty()) { + extPrefIt.remove(); + } + + } + } + return rankCloudProvidersMessage; } diff --git a/src/main/java/it/reply/orchestrator/service/commands/UpdateDeployment.java b/src/main/java/it/reply/orchestrator/service/commands/UpdateDeployment.java index d2ab991f25..fc0262d28b 100644 --- a/src/main/java/it/reply/orchestrator/service/commands/UpdateDeployment.java +++ b/src/main/java/it/reply/orchestrator/service/commands/UpdateDeployment.java @@ -2,9 +2,11 @@ import it.reply.orchestrator.dal.entity.Deployment; import it.reply.orchestrator.dal.repository.DeploymentRepository; +import it.reply.orchestrator.dto.CloudProviderEndpoint; import it.reply.orchestrator.dto.RankCloudProvidersMessage; import it.reply.orchestrator.dto.deployment.DeploymentMessage; import it.reply.orchestrator.dto.ranker.RankedCloudProvider; +import it.reply.orchestrator.service.CloudProviderEndpointServiceImpl; import it.reply.orchestrator.service.WorkflowConstants; import it.reply.orchestrator.service.deployment.providers.DeploymentStatusHelper; import it.reply.workflowmanager.spring.orchestrator.bpm.ejbcommands.BaseCommand; @@ -33,6 +35,9 @@ public class UpdateDeployment extends BaseCommand { @Autowired private DeploymentStatusHelper deploymentStatusHelper; + @Autowired + private CloudProviderEndpointServiceImpl cloudProviderEndpointServiceImpl; + @Override public ExecutionResults customExecute(CommandContext ctx) throws Exception { @@ -53,27 +58,32 @@ public ExecutionResults customExecute(CommandContext ctx) throws Exception { WorkflowConstants.WF_PARAM_DEPLOYMENT_MESSAGE)); } - // TODO: Move elsewhere + Deployment deployment = + deploymentRepository.findOne(rankCloudProvidersMessage.getDeploymentId()); + // Choose Cloud Provider - LOG.debug("Choosing Cloud Provider based on: {}", - rankCloudProvidersMessage.getRankedCloudProviders()); - - // TODO Check ranker errors (i.e. providers with ranked = false) - RankedCloudProvider chosenCp = null; - for (RankedCloudProvider rcp : rankCloudProvidersMessage.getRankedCloudProviders()) { - if (chosenCp == null || rcp.getRank() < chosenCp.getRank()) { - chosenCp = rcp; - } - } - LOG.debug("Selected Cloud Provider is: {}", chosenCp); + RankedCloudProvider chosenCp = cloudProviderEndpointServiceImpl + .chooseCloudProvider(deployment, rankCloudProvidersMessage); + + // Set the chosen CP in deploymentMessage + deploymentMessage.setChosenCloudProvider( + rankCloudProvidersMessage.getCloudProviders().get(chosenCp.getName())); // Update Deployment - Deployment deployment = - deploymentRepository.findOne(rankCloudProvidersMessage.getDeploymentId()); deployment.setCloudProviderName(chosenCp.getName()); // FIXME Set/update all required selected CP data + // FIXME Generate + CloudProviderEndpoint chosenCloudProviderEndpoint = cloudProviderEndpointServiceImpl + .getCloudProviderEndpoint(deployment, rankCloudProvidersMessage, chosenCp); + deploymentMessage.setChosenCloudProviderEndpoint(chosenCloudProviderEndpoint); + LOG.debug("Generated Cloud Provider Endpoint is: {}", chosenCloudProviderEndpoint); + + // FIXME Use another method to hold CP Endpoint (i.e. CMDB service ID reference?) + // Save CPE in Deployment for future use + deployment.setCloudProviderEndpoint(chosenCloudProviderEndpoint); + exResults.getData().putAll(resultOccurred(true).getData()); exResults.setData(WorkflowConstants.WF_PARAM_DEPLOYMENT_MESSAGE, deploymentMessage); } catch (Exception ex) { diff --git a/src/main/java/it/reply/orchestrator/service/deployment/providers/ImServiceImpl.java b/src/main/java/it/reply/orchestrator/service/deployment/providers/ImServiceImpl.java index 7dd9f82d73..df7422e1ae 100644 --- a/src/main/java/it/reply/orchestrator/service/deployment/providers/ImServiceImpl.java +++ b/src/main/java/it/reply/orchestrator/service/deployment/providers/ImServiceImpl.java @@ -3,10 +3,13 @@ import alien4cloud.model.topology.NodeTemplate; import alien4cloud.tosca.model.ArchiveRoot; import alien4cloud.tosca.parser.ParsingException; -import alien4cloud.tosca.parser.ParsingResult; import es.upv.i3m.grycap.im.InfrastructureManager; import es.upv.i3m.grycap.im.States; +import es.upv.i3m.grycap.im.auth.AuthorizationHeader; +import es.upv.i3m.grycap.im.auth.credential.Credential; +import es.upv.i3m.grycap.im.auth.credential.im.ImCredential.ImTokenCredential; +import es.upv.i3m.grycap.im.auth.credential.opennebula.OpenNebulaTokenCredential; import es.upv.i3m.grycap.im.exceptions.ImClientErrorException; import es.upv.i3m.grycap.im.exceptions.ImClientException; import es.upv.i3m.grycap.im.pojo.InfOutputValues; @@ -22,6 +25,7 @@ import it.reply.orchestrator.dal.entity.Resource; import it.reply.orchestrator.dal.repository.DeploymentRepository; import it.reply.orchestrator.dal.repository.ResourceRepository; +import it.reply.orchestrator.dto.CloudProviderEndpoint.IaaSType; import it.reply.orchestrator.dto.deployment.DeploymentMessage; import it.reply.orchestrator.enums.DeploymentProvider; import it.reply.orchestrator.enums.NodeStates; @@ -31,6 +35,7 @@ import it.reply.orchestrator.exception.service.DeploymentException; import it.reply.orchestrator.exception.service.ToscaException; import it.reply.orchestrator.service.ToscaService; +import it.reply.orchestrator.service.security.OAuth2TokenService; import it.reply.utils.json.JsonUtility; import org.apache.commons.io.IOUtils; @@ -44,11 +49,8 @@ import org.springframework.data.domain.Page; import org.springframework.stereotype.Service; -import java.io.File; -import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.io.OutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -70,6 +72,9 @@ public class ImServiceImpl extends AbstractDeploymentProviderService { @Autowired private ApplicationContext ctx; + @Autowired + private OAuth2TokenService oauth2TokenService; + @Value("${onedock.proxy.file.path}") private String proxyPath; @@ -79,9 +84,6 @@ public class ImServiceImpl extends AbstractDeploymentProviderService { @Value("${auth.file.path}") private String authFilePath; - @Value("${opennebula.auth.file.path}") - private String opennebulaAuthFilePath; - @Value("${openstack.auth.file.path}") private String openstackAuthFilePath; @@ -100,78 +102,61 @@ public class ImServiceImpl extends AbstractDeploymentProviderService { @Autowired private ResourceRepository resourceRepository; - public enum IaaSSite { - // @formatter:off - OPENSTACK, OPENNEBULA, ONEDOCK - // @formatter:on - } - - private InfrastructureManager getClient(IaaSSite iaaSSite) { - InputStream inputStream = null; + private InfrastructureManager getClient(DeploymentMessage dm) { + IaaSType iaasType = dm.getChosenCloudProviderEndpoint().getIaasType(); + String authString = null; try { - switch (iaaSSite) { + LOG.debug("Load {} credentials with: {}", iaasType, dm.getChosenCloudProviderEndpoint()); + switch (iaasType) { case OPENSTACK: - LOG.debug("Load {} credentials", IaaSSite.OPENSTACK.toString()); - - inputStream = ctx.getResource(openstackAuthFilePath).getInputStream(); - break; - case ONEDOCK: - LOG.debug("Load {} credentials", IaaSSite.ONEDOCK.toString()); - // Read the proxy file - String proxy; - try (InputStream in = ctx.getResource(proxyPath).getInputStream()) { - proxy = IOUtils.toString(in); - proxy = proxy.replace(System.lineSeparator(), "\\\\n"); - } catch (Exception ex) { - throw new OrchestratorException("Cannot load proxy file", ex); + try (InputStream is = ctx.getResource(openstackAuthFilePath).getInputStream()) { + authString = IOUtils.toString(is); + } + if (oauth2TokenService.isSecurityEnabled()) { + authString = + authString.replaceAll("InfrastructureManager; username = .+; password = .+", + "InfrastructureManager; token = " + dm.getOauth2Token()); } - // read onedock auth file - inputStream = ctx.getResource(onedockAuthFilePath).getInputStream(); - String authFile = IOUtils.toString(inputStream, StandardCharsets.UTF_8.toString()); - inputStream.close(); - - // replace the proxy as string - authFile = authFile.replace("{proxy}", proxy); - - inputStream = IOUtils.toInputStream(authFile, StandardCharsets.UTF_8.toString()); break; case OPENNEBULA: - LOG.debug("Load {} credentials", IaaSSite.OPENNEBULA.toString()); - inputStream = ctx.getResource(opennebulaAuthFilePath).getInputStream(); + if (oauth2TokenService.isSecurityEnabled()) { + AuthorizationHeader ah = new AuthorizationHeader(); + Credential cred = + ImTokenCredential.getBuilder().withToken(dm.getOauth2Token()).build(); + ah.addCredential(cred); + cred = OpenNebulaTokenCredential.getBuilder().withId("onedock") + .withHost(dm.getChosenCloudProviderEndpoint().getCpEndpoint()) + .withToken(dm.getOauth2Token()).build(); + ah.addCredential(cred); + InfrastructureManager im = new InfrastructureManager(imUrl, ah); + return im; + } else { + // Read the proxy file + String proxy; + try (InputStream in = ctx.getResource(proxyPath).getInputStream()) { + proxy = IOUtils.toString(in); + proxy = proxy.replace(System.lineSeparator(), "\\\\n"); + } catch (Exception ex) { + throw new OrchestratorException("Cannot load proxy file", ex); + } + // read onedock auth file + try (InputStream in = ctx.getResource(onedockAuthFilePath).getInputStream()) { + authString = IOUtils.toString(in, StandardCharsets.UTF_8.toString()); + } + // replace the proxy as string + authString = authString.replace("{proxy}", proxy); + } break; + // inputStream = ctx.getResource(opennebulaAuthFilePath).getInputStream(); + // break; default: - LOG.debug("Load fake credentials"); - inputStream = ctx.getResource(authFilePath).getInputStream(); - break; + throw new IllegalArgumentException( + String.format("Unsupported provider type <%s>", iaasType)); } - - File tmp = File.createTempFile("authFileTmp", ".tmp"); - try (OutputStream outStream = new FileOutputStream(tmp)) { - IOUtils.copy(inputStream, outStream); - } - InfrastructureManager im = new InfrastructureManager(imUrl, tmp.toPath()); + InfrastructureManager im = new InfrastructureManager(imUrl, authString); return im; } catch (IOException | ImClientException ex) { throw new OrchestratorException("Cannot load IM auth file", ex); - } finally { - if (inputStream != null) { - try { - inputStream.close(); - } catch (IOException ex) { - LOG.catching(ex); - } - } - } - } - - private IaaSSite getIaaSSiteFromTosca(String template) { - - if (template.contains("tosca.nodes.indigo.MesosMaster")) { - return IaaSSite.OPENSTACK; - } else if (template.contains("onedock.i3m.upv.es")) { - return IaaSSite.ONEDOCK; - } else { - return IaaSSite.OPENNEBULA; } } @@ -187,11 +172,12 @@ public boolean doDeploy(DeploymentMessage deploymentMessage) { ArchiveRoot ar = toscaService.prepareTemplate(deployment.getTemplate(), deployment.getParameters()); - toscaService.addDeploymentId(ar, deploymentUuid); + toscaService.addElasticClusterParameters(ar, deploymentUuid); + toscaService.contextualizeImages(ar, deploymentMessage.getChosenCloudProvider()); String imCustomizedTemplate = toscaService.getTemplateFromTopology(ar); - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + // Generate IM Client + InfrastructureManager im = getClient(deploymentMessage); // Deploy on IM InfrastructureUri infrastructureUri = @@ -230,8 +216,8 @@ public boolean isDeployed(DeploymentMessage deploymentMessage) throws Deployment Deployment deployment = deploymentMessage.getDeployment(); InfrastructureManager im = null; try { - // FIXME this is a trick used only for demo purpose - im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + // Generate IM Client + im = getClient(deploymentMessage); InfrastructureState infrastructureState = im.getInfrastructureState(deployment.getEndpoint()); LOG.debug(infrastructureState.toString()); @@ -257,6 +243,7 @@ public boolean isDeployed(DeploymentMessage deploymentMessage) throws Deployment } DeploymentException ex = new DeploymentException(errorMsg); updateOnError(deployment.getId(), ex); + LOG.error(errorMsg); throw ex; default: return false; @@ -279,6 +266,7 @@ public boolean isDeployed(DeploymentMessage deploymentMessage) throws Deployment } catch (Exception ex) { // Do nothing } + LOG.error(errorMsg); throw new DeploymentException(errorMsg); } } @@ -289,8 +277,9 @@ public void finalizeDeploy(DeploymentMessage deploymentMessage, boolean deployed Deployment deployment = deploymentMessage.getDeployment(); if (deployed) { try { - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + // Generate IM Client + InfrastructureManager im = getClient(deploymentMessage); + if (deployment.getOutputs().isEmpty()) { InfOutputValues outputValues = im.getInfrastructureOutputs(deployment.getEndpoint()); Map outputs = new HashMap(); @@ -303,7 +292,7 @@ public void finalizeDeploy(DeploymentMessage deploymentMessage, boolean deployed } deployment.setOutputs(outputs); } - bindResources(deployment, deployment.getEndpoint()); + bindResources(deployment, deployment.getEndpoint(), im); updateOnSuccess(deployment.getId()); @@ -327,23 +316,28 @@ public boolean doUpdate(DeploymentMessage deploymentMessage, String template) { // Check if count is increased or if there is a removal list, other kinds of update are // discarded - ParsingResult oldParsingResult; - ParsingResult newParsingResult; + ArchiveRoot oldAr; + ArchiveRoot newAr; try { // FIXME Fugly - oldParsingResult = toscaService.getArchiveRootFromTemplate(deployment.getTemplate()); - template = toscaService.customizeTemplate(template, deployment.getId()); - newParsingResult = toscaService.getArchiveRootFromTemplate(template); + + // Get TOSCA in-memory repr. of current template + oldAr = toscaService.prepareTemplate(deployment.getTemplate(), deployment.getParameters()); + + // Get TOSCA in-memory repr. of new template + newAr = toscaService.prepareTemplate(template, deployment.getParameters()); + toscaService.addElasticClusterParameters(newAr, deployment.getId()); + toscaService.contextualizeImages(newAr, deploymentMessage.getChosenCloudProvider()); } catch (ParsingException | IOException | ToscaException ex) { throw new OrchestratorException(ex); } // find Count nodes into new and old template - Map oldNodes = toscaService.getCountNodes(oldParsingResult.getResult()); - Map newNodes = toscaService.getCountNodes(newParsingResult.getResult()); + Map oldNodes = toscaService.getCountNodes(oldAr); + Map newNodes = toscaService.getCountNodes(newAr); try { // Create the new template with the nodes to be added - ArchiveRoot root = newParsingResult.getResult(); + ArchiveRoot root = newAr; Map nodes = new HashMap<>(); // List of vmIds to be removed @@ -404,13 +398,14 @@ public boolean doUpdate(DeploymentMessage deploymentMessage, String template) { } } + // Generate IM Client + InfrastructureManager im = getClient(deploymentMessage); + // Pulisco gli output e aggiungo i nodi da creare root.getTopology().setOutputs(null); root.getTopology().setNodeTemplates(nodes); if (!root.getTopology().isEmpty()) { try { - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); - im.addResource(deployment.getEndpoint(), toscaService.getTemplateFromTopology(root), BodyContentType.TOSCA); } catch (ImClientErrorException exception) { @@ -421,8 +416,6 @@ public boolean doUpdate(DeploymentMessage deploymentMessage, String template) { // DELETE if (vmIds.size() > 0) { try { - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); im.removeResource(deployment.getEndpoint(), vmIds); } catch (ImClientErrorException exception) { throw new DeploymentException( @@ -447,8 +440,9 @@ public boolean doUndeploy(DeploymentMessage deploymentMessage) { deployment.setTask(Task.DEPLOYER); deployment = deploymentRepository.save(deployment); - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + // Generate IM Client + InfrastructureManager im = getClient(deploymentMessage); + if (deployment.getEndpoint() == null) { // updateOnSuccess(deploymentUuid); deploymentMessage.setDeleteComplete(true); @@ -482,8 +476,8 @@ public boolean isUndeployed(DeploymentMessage deploymentMessage) { Deployment deployment = deploymentMessage.getDeployment(); try { - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + // Generate IM Client + InfrastructureManager im = getClient(deploymentMessage); // TODO verificare if (deployment.getEndpoint() == null) { @@ -518,35 +512,32 @@ public void finalizeUndeploy(DeploymentMessage deploymentMessage, boolean undepl } } - private boolean isResourceDeleted(Resource resource) { - try { - Deployment deployment = resource.getDeployment(); - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); - - im.getVmInfo(deployment.getEndpoint(), resource.getIaasId()); - return false; - - } catch (ImClientErrorException exception) { - ResponseError error = getImResponseError(exception); - return error.is404Error(); - - } catch (ImClientException ex) { - // TODO improve exception handling - LOG.error(ex); - return false; - } - } + // private boolean isResourceDeleted(Resource resource) { + // try { + // Deployment deployment = resource.getDeployment(); + // // Generate IM Client + // InfrastructureManager im = getClient(deploymentMessage); + // + // im.getVmInfo(deployment.getEndpoint(), resource.getIaasId()); + // return false; + // + // } catch (ImClientErrorException exception) { + // ResponseError error = getImResponseError(exception); + // return error.is404Error(); + // + // } catch (ImClientException ex) { + // // TODO improve exception handling + // LOG.error(ex); + // return false; + // } + // } /** * Match the {@link Resource} to IM vms. * */ - private void bindResources(Deployment deployment, String infrastructureId) - throws ImClientException { - - // FIXME this is a trick used only for demo purpose - InfrastructureManager im = getClient(getIaaSSiteFromTosca(deployment.getTemplate())); + private void bindResources(Deployment deployment, String infrastructureId, + InfrastructureManager im) throws ImClientException { // Get the URLs of the VMs composing the virtual infrastructure // TODO test in case of errors @@ -613,7 +604,11 @@ private void logImErrorResponse(ImClientErrorException exception) { * @param message * the error message */ + @Override public void updateOnError(String deploymentUuid, String message) { + // WARNING: In IM we don't have the resource mapping yet, so we update all the resources + // FIXME Remove once IM handles single nodes state update!!!! And pay attention to the + // AbstractDeploymentProviderService.updateOnError method! Deployment deployment = deploymentRepository.findOne(deploymentUuid); switch (deployment.getStatus()) { case CREATE_FAILED: @@ -642,7 +637,12 @@ public void updateOnError(String deploymentUuid, String message) { break; } deployment.setTask(Task.NONE); - deployment.setStatusReason(message); + // Do not delete a previous statusReason if there's no explicit value! (used when isDeploy + // reports an error and then the PollDeploy task calls the finalizeDeploy, which also uses this + // method but does not have any newer statusReason) + if (message != null) { + deployment.setStatusReason(message); + } deploymentRepository.save(deployment); } } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 125a309b58..c258819962 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -12,4 +12,7 @@ tosca.definitions.indigo=custom_types.yaml # TEMPORARY - Chronos auth file path (default value to read the files as classpath resource) chronos.auth.file.path=classpath:chronos/chronos.properties -orchestrator.chronos.jobChunkSize=100 \ No newline at end of file +orchestrator.chronos.jobChunkSize=100 + +# The base URL which the Orchestrator is available to (it MUST be accessible for the ElasticCluster callbacks!) +orchestrator.url=http://localhost:8081 \ No newline at end of file diff --git a/src/main/resources/cloud-provider-ranker/cloud-provider-ranker.properties b/src/main/resources/cloud-provider-ranker/cloud-provider-ranker.properties index a511fbeca2..769a77e76e 100644 --- a/src/main/resources/cloud-provider-ranker/cloud-provider-ranker.properties +++ b/src/main/resources/cloud-provider-ranker/cloud-provider-ranker.properties @@ -1 +1 @@ -cloud-provider-ranker.url=http://a.it/ \ No newline at end of file +cloud-provider-ranker.url=http://indigo-ranker.pd.infn.it:8443/rank \ No newline at end of file diff --git a/src/test/java/it/reply/orchestrator/command/GetCMDBDataCommandTest.java b/src/test/java/it/reply/orchestrator/command/GetCMDBDataCommandTest.java index 44d1c283eb..48b3db4264 100644 --- a/src/test/java/it/reply/orchestrator/command/GetCMDBDataCommandTest.java +++ b/src/test/java/it/reply/orchestrator/command/GetCMDBDataCommandTest.java @@ -37,7 +37,7 @@ public void doexecuteSuccesfully() throws Exception { RankCloudProvidersWorkflowTest.mockCmdb(mockServer, cmdbService.getUrl()); ExecutionResults er = executeCommand(JsonUtility.deserializeJson( - "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":null,\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":null,\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e8040f\":null}},\"provider-UPV-GRyCAP\":{\"name\":null,\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":null,\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e6f4bc\":null}}},\"cloudProvidersMonitoringData\":{},\"rankedCloudProviders\":[]}", + "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":null,\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":null,\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e6f4bc\":null},\"cmdbProviderImages\":[]},\"provider-UPV-GRyCAP\":{\"name\":null,\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":null,\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":null},\"cmdbProviderImages\":[]}},\"cloudProvidersMonitoringData\":{},\"rankedCloudProviders\":[]}", RankCloudProvidersMessage.class)); assertEquals(true, commandSucceeded(er)); diff --git a/src/test/java/it/reply/orchestrator/command/GetMonitoringDataCommandTest.java b/src/test/java/it/reply/orchestrator/command/GetMonitoringDataCommandTest.java index fdea53f357..b9422b6217 100644 --- a/src/test/java/it/reply/orchestrator/command/GetMonitoringDataCommandTest.java +++ b/src/test/java/it/reply/orchestrator/command/GetMonitoringDataCommandTest.java @@ -37,7 +37,7 @@ public void doexecuteSuccesfully() throws Exception { RankCloudProvidersWorkflowTest.mockMonitoring(mockServer, monitoringService.getUrl()); ExecutionResults er = executeCommand(JsonUtility.deserializeJson( - "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":\"provider-RECAS-BARI\",\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":{\"_id\":\"provider-RECAS-BARI\",\"_rev\":\"1-c7dbe4d8be30aa4c0f14d3ad0411d962\",\"data\":{\"id\":\"476\",\"primary_key\":\"83757G0\",\"name\":\"RECAS-BARI\",\"country\":\"Italy\",\"country_code\":\"IT\",\"roc\":\"NGI_IT\",\"subgrid\":\"\",\"giis_url\":\"ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e8040f\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}}},\"provider-UPV-GRyCAP\":{\"name\":\"provider-UPV-GRyCAP\",\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":{\"_id\":\"provider-UPV-GRyCAP\",\"_rev\":\"1-0a5ba48b2d6e0c26d36b0e3e81175352\",\"data\":{\"id\":\"458\",\"primary_key\":\"135G0\",\"name\":\"UPV-GRyCAP\",\"country\":\"Spain\",\"country_code\":\"ES\",\"roc\":\"NGI_IBERGRID\",\"subgrid\":\"\",\"giis_url\":\"ldap://ngiesbdii.i3m.upv.es:2170/mds-vo-name=UPV-GRyCAP,o=grid\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e6f4bc\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}}}},\"cloudProvidersMonitoringData\":{},\"rankedCloudProviders\":[]}", + "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":\"provider-RECAS-BARI\",\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":{\"_id\":\"provider-RECAS-BARI\",\"_rev\":\"1-c7dbe4d8be30aa4c0f14d3ad0411d962\",\"data\":{\"id\":\"476\",\"primary_key\":\"83757G0\",\"name\":\"RECAS-BARI\",\"country\":\"Italy\",\"country_code\":\"IT\",\"roc\":\"NGI_IT\",\"subgrid\":\"\",\"giis_url\":\"ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}}},\"provider-UPV-GRyCAP\":{\"name\":\"provider-UPV-GRyCAP\",\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":{\"_id\":\"provider-UPV-GRyCAP\",\"_rev\":\"1-0a5ba48b2d6e0c26d36b0e3e81175352\",\"data\":{\"id\":\"458\",\"primary_key\":\"135G0\",\"name\":\"UPV-GRyCAP\",\"country\":\"Spain\",\"country_code\":\"ES\",\"roc\":\"NGI_IBERGRID\",\"subgrid\":\"\",\"giis_url\":\"ldap://ngiesbdii.i3m.upv.es:2170/mds-vo-name=UPV-GRyCAP,o=grid\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}}}},\"cloudProvidersMonitoringData\":{},\"rankedCloudProviders\":[]}", RankCloudProvidersMessage.class)); assertEquals(true, commandSucceeded(er)); diff --git a/src/test/java/it/reply/orchestrator/command/GetProvidersRankCommandTest.java b/src/test/java/it/reply/orchestrator/command/GetProvidersRankCommandTest.java index 71dcba2a02..da42d2b8aa 100644 --- a/src/test/java/it/reply/orchestrator/command/GetProvidersRankCommandTest.java +++ b/src/test/java/it/reply/orchestrator/command/GetProvidersRankCommandTest.java @@ -37,7 +37,7 @@ public void doexecuteSuccesfully() throws Exception { RankCloudProvidersWorkflowTest.mockCpr(mockServer, cloudProviderRankerService.getUrl()); ExecutionResults er = executeCommand(JsonUtility.deserializeJson( - "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":\"provider-RECAS-BARI\",\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":{\"_id\":\"provider-RECAS-BARI\",\"_rev\":\"1-c7dbe4d8be30aa4c0f14d3ad0411d962\",\"data\":{\"id\":\"476\",\"primary_key\":\"83757G0\",\"name\":\"RECAS-BARI\",\"country\":\"Italy\",\"country_code\":\"IT\",\"roc\":\"NGI_IT\",\"subgrid\":\"\",\"giis_url\":\"ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e8040f\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}}},\"provider-UPV-GRyCAP\":{\"name\":\"provider-UPV-GRyCAP\",\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":{\"_id\":\"provider-UPV-GRyCAP\",\"_rev\":\"1-0a5ba48b2d6e0c26d36b0e3e81175352\",\"data\":{\"id\":\"458\",\"primary_key\":\"135G0\",\"name\":\"UPV-GRyCAP\",\"country\":\"Spain\",\"country_code\":\"ES\",\"roc\":\"NGI_IBERGRID\",\"subgrid\":\"\",\"giis_url\":\"ldap://ngiesbdii.i3m.upv.es:2170/mds-vo-name=UPV-GRyCAP,o=grid\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e6f4bc\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}}}},\"cloudProvidersMonitoringData\":{\"provider-RECAS-BARI\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}],\"provider-UPV-GRyCAP\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}]},\"rankedCloudProviders\":[]}", + "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":\"provider-RECAS-BARI\",\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":{\"_id\":\"provider-RECAS-BARI\",\"_rev\":\"1-c7dbe4d8be30aa4c0f14d3ad0411d962\",\"data\":{\"id\":\"476\",\"primary_key\":\"83757G0\",\"name\":\"RECAS-BARI\",\"country\":\"Italy\",\"country_code\":\"IT\",\"roc\":\"NGI_IT\",\"subgrid\":\"\",\"giis_url\":\"ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}}},\"provider-UPV-GRyCAP\":{\"name\":\"provider-UPV-GRyCAP\",\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":{\"_id\":\"provider-UPV-GRyCAP\",\"_rev\":\"1-0a5ba48b2d6e0c26d36b0e3e81175352\",\"data\":{\"id\":\"458\",\"primary_key\":\"135G0\",\"name\":\"UPV-GRyCAP\",\"country\":\"Spain\",\"country_code\":\"ES\",\"roc\":\"NGI_IBERGRID\",\"subgrid\":\"\",\"giis_url\":\"ldap://ngiesbdii.i3m.upv.es:2170/mds-vo-name=UPV-GRyCAP,o=grid\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}}}},\"cloudProvidersMonitoringData\":{\"provider-RECAS-BARI\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}],\"provider-UPV-GRyCAP\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}]},\"rankedCloudProviders\":[]}", RankCloudProvidersMessage.class)); assertEquals(true, commandSucceeded(er)); diff --git a/src/test/java/it/reply/orchestrator/config/ApplicationConfigTest.java b/src/test/java/it/reply/orchestrator/config/ApplicationConfigTest.java index a0a8b948cb..27faebeb5b 100644 --- a/src/test/java/it/reply/orchestrator/config/ApplicationConfigTest.java +++ b/src/test/java/it/reply/orchestrator/config/ApplicationConfigTest.java @@ -10,7 +10,7 @@ @ComponentScan(basePackages = { "it.reply.orchestrator", "it.reply.workflowmanager" }, excludeFilters = { @ComponentScan.Filter(type = FilterType.REGEX, pattern = "it.reply.orchestrator.config.specific.*") }) -public class ApplicationConfigTest { +public class ApplicationConfigTest extends ApplicationConfig { @Bean public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { diff --git a/src/test/java/it/reply/orchestrator/config/specific/WebAppConfigurationAware.java b/src/test/java/it/reply/orchestrator/config/specific/WebAppConfigurationAware.java index 5906595b84..0d5c84c5b5 100644 --- a/src/test/java/it/reply/orchestrator/config/specific/WebAppConfigurationAware.java +++ b/src/test/java/it/reply/orchestrator/config/specific/WebAppConfigurationAware.java @@ -4,7 +4,7 @@ import com.github.springtestdbunit.DbUnitTestExecutionListener; -import it.reply.orchestrator.config.ApplicationConfig; +import it.reply.orchestrator.config.ApplicationConfigTest; import it.reply.orchestrator.config.PersistenceConfigTest; import it.reply.orchestrator.config.WebAppInitializer; import it.reply.orchestrator.config.WebMvcConfig; @@ -37,7 +37,7 @@ @WebAppConfiguration @ContextHierarchy({ @ContextConfiguration(name = "baseContext", - classes = { ApplicationConfig.class, WebAppInitializer.class, WebMvcConfig.class, + classes = { ApplicationConfigTest.class, WebAppInitializer.class, WebMvcConfig.class, PersistenceConfigTest.class, WorklfowPersistenceConfigTest.class }), @ContextConfiguration(name = "workflowContext", classes = { WebAppConfigurationAware.Config.class }) }) diff --git a/src/test/java/it/reply/orchestrator/service/CloudProviderRankerServiceTest.java b/src/test/java/it/reply/orchestrator/service/CloudProviderRankerServiceTest.java index 66243a56f4..a87476e446 100644 --- a/src/test/java/it/reply/orchestrator/service/CloudProviderRankerServiceTest.java +++ b/src/test/java/it/reply/orchestrator/service/CloudProviderRankerServiceTest.java @@ -1,58 +1,55 @@ package it.reply.orchestrator.service; import static org.junit.Assert.assertEquals; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.method; -import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; -import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import it.reply.orchestrator.config.specific.WebAppConfigurationAwareIT; +import it.reply.orchestrator.dto.RankCloudProvidersMessage; import it.reply.orchestrator.dto.ranker.CloudProviderRankerRequest; +import it.reply.orchestrator.dto.ranker.Monitoring; import it.reply.orchestrator.dto.ranker.RankedCloudProvider; import it.reply.utils.json.JsonUtility; -import org.junit.Before; import org.junit.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; -import org.springframework.test.web.client.MockRestServiceServer; -import org.springframework.web.client.RestTemplate; import java.util.Arrays; import java.util.List; - +import java.util.stream.Collectors; + +/** + * This integration test makes real request to the CloudProviderRanker APIs. + * + * @author l.biava + * + */ public class CloudProviderRankerServiceTest extends WebAppConfigurationAwareIT { @Autowired private CloudProviderRankerService cloudProviderRankerService; - private MockRestServiceServer mockServer; + @Test + public void rankProviders() throws Exception { - @Autowired - private RestTemplate restTemplate; + RankCloudProvidersMessage rcpm = JsonUtility.deserializeJson( + "{\"deploymentId\":\"mmd34483-d937-4578-bfdb-ebe196bf82dd\",\"slamPreferences\":{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]},\"cloudProviders\":{\"provider-RECAS-BARI\":{\"name\":\"provider-RECAS-BARI\",\"id\":\"provider-RECAS-BARI\",\"cmdbProviderData\":{\"_id\":\"provider-RECAS-BARI\",\"_rev\":\"1-c7dbe4d8be30aa4c0f14d3ad0411d962\",\"data\":{\"id\":\"476\",\"primary_key\":\"83757G0\",\"name\":\"RECAS-BARI\",\"country\":\"Italy\",\"country_code\":\"IT\",\"roc\":\"NGI_IT\",\"subgrid\":\"\",\"giis_url\":\"ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}}},\"provider-UPV-GRyCAP\":{\"name\":\"provider-UPV-GRyCAP\",\"id\":\"provider-UPV-GRyCAP\",\"cmdbProviderData\":{\"_id\":\"provider-UPV-GRyCAP\",\"_rev\":\"1-0a5ba48b2d6e0c26d36b0e3e81175352\",\"data\":{\"id\":\"458\",\"primary_key\":\"135G0\",\"name\":\"UPV-GRyCAP\",\"country\":\"Spain\",\"country_code\":\"ES\",\"roc\":\"NGI_IBERGRID\",\"subgrid\":\"\",\"giis_url\":\"ldap://ngiesbdii.i3m.upv.es:2170/mds-vo-name=UPV-GRyCAP,o=grid\"},\"type\":\"provider\"},\"cmdbProviderServices\":{\"4401ac5dc8cfbbb737b0a02575e81d9b\":{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}}}},\"cloudProvidersMonitoringData\":{\"provider-RECAS-BARI\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-RECAS-BARI..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}],\"provider-UPV-GRyCAP\":[{\"metricName\":\"OCCI Create VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Create VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI CreateVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI CreateVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Delete VM Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Delete VM Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI DeleteVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI DeleteVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"General OCCI API Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..General OCCI API Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI Inspect VM availability\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI Inspect VM availability\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Response Time\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Response Time\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"ms\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]},{\"metricName\":\"OCCI InspectVM Result\",\"metricKey\":\"Cloud_Providers.provider-UPV-GRyCAP..OCCI InspectVM Result\",\"metricValue\":0.0,\"metricTime\":\"Instant null because no metrics were returned in the last 24hs\",\"metricUnit\":\"bit\",\"paasThresholds\":[],\"historyClocks\":[],\"historyValues\":[]}]},\"rankedCloudProviders\":[]}", + RankCloudProvidersMessage.class); - @Before - public void setUp() { - mockServer = MockRestServiceServer.createServer(restTemplate); - } + // Prepare Ranker's request + List monitoring = rcpm.getCloudProvidersMonitoringData().entrySet().stream() + .map(e -> new Monitoring(e.getKey(), e.getValue())).collect(Collectors.toList()); - @Test - public void doCallback() throws Exception { + CloudProviderRankerRequest cprr = new CloudProviderRankerRequest() + .withPreferences(rcpm.getSlamPreferences().getPreferences().get(0).getPreferences()) + .withSla(rcpm.getSlamPreferences().getSla()).withMonitoring(monitoring); + // WARNING: This is hard-coded and may change in the future! List response = - Arrays.asList(new RankedCloudProvider("Name1", 1, true, ""), - new RankedCloudProvider("Name2", 0, false, "Error msg")); - - mockServer.expect(requestTo(cloudProviderRankerService.getUrl())) - .andExpect(method(HttpMethod.POST)) - .andRespond(withSuccess(JsonUtility.serializeJson(response), MediaType.APPLICATION_JSON)); + Arrays.asList(new RankedCloudProvider("provider-RECAS-BARI", 2.0f, true, ""), + new RankedCloudProvider("provider-UPV-GRyCAP", 1.0f, true, "")); - List result = - cloudProviderRankerService.getProviderRanking(new CloudProviderRankerRequest()); + List result = cloudProviderRankerService.getProviderRanking(cprr); assertEquals(response, result); - mockServer.verify(); - } } diff --git a/src/test/java/it/reply/orchestrator/service/CmdbServiceIT.java b/src/test/java/it/reply/orchestrator/service/CmdbServiceIT.java index 7554e61436..db30e27a56 100644 --- a/src/test/java/it/reply/orchestrator/service/CmdbServiceIT.java +++ b/src/test/java/it/reply/orchestrator/service/CmdbServiceIT.java @@ -1,76 +1,77 @@ -// package it.reply.orchestrator.service; -// -// import static org.junit.Assert.assertEquals; -// -// import it.reply.orchestrator.config.specific.WebAppConfigurationAwareIT; -// import it.reply.orchestrator.dto.cmdb.Data; -// import it.reply.orchestrator.dto.cmdb.Provider; -// import it.reply.orchestrator.dto.cmdb.ProviderData; -// import it.reply.orchestrator.dto.cmdb.Service; -// import it.reply.orchestrator.dto.cmdb.Type; -// -// import org.junit.Before; -// import org.junit.Test; -// import org.springframework.beans.factory.annotation.Autowired; -// import org.springframework.web.client.RestTemplate; -// -// public class CmdbServiceIT extends WebAppConfigurationAwareIT { -// -// private final String recasId = "4401ac5dc8cfbbb737b0a02575e6f4bc"; -// private final String recasProviderName = "provider-RECAS-BARI"; -// -// @Autowired -// private CmdbService service; -// -// // private MockRestServiceServer mockServer; -// -// @Autowired -// private RestTemplate restTemplate; -// -// @Before -// public void setUp() { -// // mockServer = MockRestServiceServer.createServer(restTemplate); -// } -// -// @Test -// public void getServiceTest() throws Exception { -// -// // mockServer.expect(requestTo("http://test-server.com")).andExpect(method(HttpMethod.POST)) -// // .andRespond(withSuccess()); -// -// Service serviceRecas = service.getServiceById(recasId); -// Data data = new Data().withServiceType("eu.egi.cloud.vm-management.openstack") -// .withEndpoint("http://cloud.recas.ba.infn.it:5000/v2.0") -// .withProviderId("provider-RECAS-BARI").withType(Type.COMPUTE); -// -// Service service = new Service().withId(recasId).withRev("1-256d36283315ea9bb045e6d5038657b6") -// .withType("service").withData(data); -// -// assertEquals(service, serviceRecas); -// -// // mockServer.verify(); -// -// } -// -// @Test -// public void getProviderTest() throws Exception { -// -// // mockServer.expect(requestTo("http://test-server.com")).andExpect(method(HttpMethod.POST)) -// // .andRespond(withSuccess()); -// -// Provider providerRecas = service.getProviderById(recasProviderName); -// ProviderData data = -// new ProviderData().withId("476").withPrimaryKey("83757G0").withName("RECAS-BARI") -// .withCountry("Italy").withCountryCode("IT").withRoc("NGI_IT").withSubgrid("") -// .withGiisUrl("ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue"); -// -// Provider provider = new Provider().withId(recasProviderName) -// .withRev("1-c7dbe4d8be30aa4c0f14d3ad0411d962").withType("provider").withData(data); -// -// assertEquals(provider, providerRecas); -// -// // mockServer.verify(); -// -// } -// -// } +package it.reply.orchestrator.service; + +import static org.junit.Assert.assertEquals; + +import it.reply.orchestrator.config.specific.WebAppConfigurationAwareIT; +import it.reply.orchestrator.dto.cmdb.CmdbImage; +import it.reply.orchestrator.dto.cmdb.Data; +import it.reply.orchestrator.dto.cmdb.Provider; +import it.reply.orchestrator.dto.cmdb.ProviderData; +import it.reply.orchestrator.dto.cmdb.Service; +import it.reply.orchestrator.dto.cmdb.Type; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.List; + +/** + * This integration test makes real request to the CMDB APIs. + * + * @author l.biava + * + */ +public class CmdbServiceIT extends WebAppConfigurationAwareIT { + + private final String recasId = "4401ac5dc8cfbbb737b0a02575e6f4bc"; + private final String recasProviderName = "provider-RECAS-BARI"; + + @Autowired + private CmdbService service; + + @Test + public void getServiceTest() throws Exception { + + Service serviceRecas = service.getServiceById(recasId); + Data data = new Data().withServiceType("eu.egi.cloud.vm-management.openstack") + .withEndpoint("http://cloud.recas.ba.infn.it:5000/v2.0") + .withProviderId("provider-RECAS-BARI").withType(Type.COMPUTE); + + Service service = new Service().withId(recasId).withRev("1-256d36283315ea9bb045e6d5038657b6") + .withType("service").withData(data); + + assertEquals(service, serviceRecas); + } + + @Test + public void getProviderTest() throws Exception { + Provider providerRecas = service.getProviderById(recasProviderName); + ProviderData data = + new ProviderData().withId("476").withPrimaryKey("83757G0").withName("RECAS-BARI") + .withCountry("Italy").withCountryCode("IT").withRoc("NGI_IT").withSubgrid("") + .withGiisUrl("ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue"); + + Provider provider = new Provider().withId(recasProviderName) + .withRev("1-c7dbe4d8be30aa4c0f14d3ad0411d962").withType("provider").withData(data); + + assertEquals(provider, providerRecas); + } + + @Test + public void getImageForServiceTest() throws Exception { + + List recasImages = service.getImagesByService(recasId); + + // ProviderData data = + // new ProviderData().withId("476").withPrimaryKey("83757G0").withName("RECAS-BARI") + // .withCountry("Italy").withCountryCode("IT").withRoc("NGI_IT").withSubgrid("") + // .withGiisUrl("ldap://cloud-bdii.recas.ba.infn.it:2170/GLUE2DomainID=RECAS-BARI,o=glue"); + // + // Provider p = new Provider().withId(recasProviderName) + // .withRev("1-c7dbe4d8be30aa4c0f14d3ad0411d962").withType("provider").withData(data); + + // assertEquals(p, providerRecas); + + } + +} diff --git a/src/test/java/it/reply/orchestrator/service/SlamServiceIT.java b/src/test/java/it/reply/orchestrator/service/SlamServiceIT.java index e0124672fd..e1f9742925 100644 --- a/src/test/java/it/reply/orchestrator/service/SlamServiceIT.java +++ b/src/test/java/it/reply/orchestrator/service/SlamServiceIT.java @@ -1,41 +1,28 @@ -// package it.reply.orchestrator.service; -// -// import static org.junit.Assert.assertEquals; -// -// import it.reply.orchestrator.config.specific.WebAppConfigurationAwareIT; -// import it.reply.orchestrator.dto.slam.SlamPreferences; -// -// import org.junit.Before; -// import org.junit.Test; -// import org.springframework.beans.factory.annotation.Autowired; -// -// public class SlamServiceIT extends WebAppConfigurationAwareIT { -// -// @Autowired -// private SlamService service; -// -// // private MockRestServiceServer mockServer; -// -// // @Autowired -// // private RestTemplate restTemplate; -// -// @Before -// public void setUp() { -// // mockServer = MockRestServiceServer.createServer(restTemplate); -// } -// -// @Test -// public void getPreferencesTest() throws Exception { -// -// // mockServer.expect(requestTo("http://test-server.com")).andExpect(method(HttpMethod.POST)) -// // .andRespond(withSuccess()); -// -// SlamPreferences pref = service.getCustomerPreferences(); -// -// assertEquals("4401ac5dc8cfbbb737b0a02575ee3b58", pref.getSla().get(0).getId()); -// -// // mockServer.verify(); -// -// } -// -// } +package it.reply.orchestrator.service; + +import static org.junit.Assert.assertEquals; + +import it.reply.orchestrator.config.specific.WebAppConfigurationAwareIT; +import it.reply.orchestrator.dto.slam.SlamPreferences; + +import org.junit.Test; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * This integration test makes real request to the SLAM APIs. + * + * @author l.biava + * + */ +public class SlamServiceIT extends WebAppConfigurationAwareIT { + + @Autowired + private SlamService service; + + @Test + public void getPreferencesTest() throws Exception { + SlamPreferences pref = service.getCustomerPreferences(); + assertEquals("4401ac5dc8cfbbb737b0a02575ee3b58", pref.getSla().get(0).getId()); + } + +} diff --git a/src/test/java/it/reply/orchestrator/service/ToscaServiceTest.java b/src/test/java/it/reply/orchestrator/service/ToscaServiceTest.java index ad92a424e4..374e990263 100644 --- a/src/test/java/it/reply/orchestrator/service/ToscaServiceTest.java +++ b/src/test/java/it/reply/orchestrator/service/ToscaServiceTest.java @@ -2,6 +2,7 @@ import static org.hamcrest.CoreMatchers.instanceOf; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThat; import alien4cloud.model.components.AbstractPropertyValue; @@ -26,6 +27,7 @@ import org.springframework.beans.factory.annotation.Autowired; import java.io.IOException; +import java.net.URL; import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; @@ -46,7 +48,7 @@ public class ToscaServiceTest extends WebAppConfigurationAware { private String deploymentId = "deployment_id"; @Test(expected = ToscaException.class) - public void customizeTemplateWithError() throws Exception { + public void customizeTemplateWithInvalidTemplate() throws Exception { String template = getFileContentAsString(TEMPLATES_BASE_DIR + "galaxy_tosca_clues_error.yaml"); toscaService.customizeTemplate(template, deploymentId); @@ -54,22 +56,28 @@ public void customizeTemplateWithError() throws Exception { @SuppressWarnings("unchecked") @Test - public void customizeTemplateWithDeplymentIdSuccessfully() throws Exception { + public void customizeTemplate() throws Exception { String template = getFileContentAsString(TEMPLATES_BASE_DIR + "galaxy_tosca_clues.yaml"); String customizedTemplate = toscaService.customizeTemplate(template, deploymentId); - String templateDeploymentId = ""; Map nodes = toscaService.getArchiveRootFromTemplate(customizedTemplate) .getResult().getTopology().getNodeTemplates(); + for (Map.Entry entry : nodes.entrySet()) { if (entry.getValue().getType().equals("tosca.nodes.indigo.ElasticCluster")) { - templateDeploymentId = + String templateDeploymentId = ((PropertyValue) entry.getValue().getProperties().get("deployment_id")) .getValue(); + + String templateOrchestratorUrl = + ((PropertyValue) entry.getValue().getProperties().get("orchestrator_url")) + .getValue(); + + assertEquals(deploymentId, templateDeploymentId); + assertNotNull(new URL(templateOrchestratorUrl)); } } - assertEquals(deploymentId, templateDeploymentId); } @Test diff --git a/src/test/java/it/reply/orchestrator/workflow/RankCloudProvidersWorkflowTest.java b/src/test/java/it/reply/orchestrator/workflow/RankCloudProvidersWorkflowTest.java index 3e9575541d..38ecdb2aa4 100644 --- a/src/test/java/it/reply/orchestrator/workflow/RankCloudProvidersWorkflowTest.java +++ b/src/test/java/it/reply/orchestrator/workflow/RankCloudProvidersWorkflowTest.java @@ -132,7 +132,7 @@ public void testProcess() throws Exception { public static void mockSlam(MockRestServiceServer mockServer, String baseUrl) throws Exception { String response = - "{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_limit\":100,\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]}"; + "{\"preferences\":[{\"customer\":\"indigo-dc\",\"preferences\":[{\"service_type\":\"compute\",\"priority\":[{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"weight\":0.5},{\"sla_id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"weight\":0.5}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee0e55\"}],\"sla\":[{\"customer\":\"indigo-dc\",\"provider\":\"provider-UPV-GRyCAP\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"targets\":[{\"type\":\"public_ip\",\"unit\":\"none\",\"restrictions\":{\"total_limit\":100,\"total_guaranteed\":10}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee3b58\"},{\"customer\":\"indigo-dc\",\"provider\":\"provider-RECAS-BARI\",\"start_date\":\"11.01.2016+15:50:00\",\"end_date\":\"11.02.2016+15:50:00\",\"services\":[{\"type\":\"compute\",\"service_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"targets\":[{\"type\":\"computing_time\",\"unit\":\"h\",\"restrictions\":{\"total_guaranteed\":200}}]}],\"id\":\"4401ac5dc8cfbbb737b0a02575ee53f6\"}]}"; mockServer.expect(requestTo(baseUrl + "preferences/indigo-dc")) .andExpect(method(HttpMethod.GET)) @@ -148,10 +148,19 @@ public static void mockCmdb(MockRestServiceServer mockServer, String baseUrl) th MediaType.APPLICATION_JSON)); // Service: Compute on provider-RECAS-BARI - mockServer.expect(requestTo(baseUrl + "service/id/4401ac5dc8cfbbb737b0a02575e8040f")) + mockServer.expect(requestTo(baseUrl + "service/id/4401ac5dc8cfbbb737b0a02575e6f4bc")) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess( + "{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}", + MediaType.APPLICATION_JSON)); + + // Images: Compute service on provider-RECAS-BARI + mockServer + .expect(requestTo(baseUrl + + "service/id/4401ac5dc8cfbbb737b0a02575e6f4bc/has_many/images?include_docs=true")) .andExpect(method(HttpMethod.GET)) .andRespond(withSuccess( - "{\"_id\":\"4401ac5dc8cfbbb737b0a02575e8040f\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}", + "{\n \"total_rows\": 44,\n \"offset\": 3,\n \"rows\": [\n {\n \"id\": \"7efc59c5db69ea67c5100de0f726d41e\",\n \"key\": [\n \"4401ac5dc8cfbbb737b0a02575e6f4bc\",\n \"images\"\n ],\n \"value\": {\n \"image_id\": \"303d8324-69a7-4372-be24-1d68703affd7\",\n \"image_name\": \"indigodatacloud/ubuntu-sshd:14.04-devel\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e6f4bc\"\n },\n \"doc\": {\n \"_id\": \"7efc59c5db69ea67c5100de0f726d41e\",\n \"_rev\": \"1-583b38e80f989b7f39b8ddd5d28c4c76\",\n \"type\": \"image\",\n \"data\": {\n \"image_id\": \"303d8324-69a7-4372-be24-1d68703affd7\",\n \"image_name\": \"indigodatacloud/ubuntu-sshd:14.04-devel\",\n \"architecture\": \"x86_64\",\n \"type\": \"linux\",\n \"distribution\": \"ubuntu\",\n \"version\": \"14.04\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e6f4bc\"\n }\n }\n },\n {\n \"id\": \"7efc59c5db69ea67c5100de0f726e0a0\",\n \"key\": [\n \"4401ac5dc8cfbbb737b0a02575e6f4bc\",\n \"images\"\n ],\n \"value\": {\n \"image_id\": \"0de96743-4a12-4470-b8b2-6dc260977a40\",\n \"image_name\": \"indigodatacloud/centos-sshd:7-devel\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e6f4bc\"\n },\n \"doc\": {\n \"_id\": \"7efc59c5db69ea67c5100de0f726e0a0\",\n \"_rev\": \"1-948dae5f4b7e1096036af3f0cca37f89\",\n \"type\": \"image\",\n \"data\": {\n \"image_id\": \"0de96743-4a12-4470-b8b2-6dc260977a40\",\n \"image_name\": \"indigodatacloud/centos-sshd:7-devel\",\n \"architecture\": \"x86_64\",\n \"type\": \"linux\",\n \"distribution\": \"centos\",\n \"version\": \"7\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e6f4bc\"\n }\n }\n }\n ]\n}", MediaType.APPLICATION_JSON)); // Provider: provider-UPV-GRyCAP @@ -162,10 +171,19 @@ public static void mockCmdb(MockRestServiceServer mockServer, String baseUrl) th MediaType.APPLICATION_JSON)); // Service: Compute on provider-UPV-GRyCAP - mockServer.expect(requestTo(baseUrl + "service/id/4401ac5dc8cfbbb737b0a02575e6f4bc")) + mockServer.expect(requestTo(baseUrl + "service/id/4401ac5dc8cfbbb737b0a02575e81d9b")) .andExpect(method(HttpMethod.GET)) .andRespond(withSuccess( - "{\"_id\":\"4401ac5dc8cfbbb737b0a02575e6f4bc\",\"_rev\":\"1-256d36283315ea9bb045e6d5038657b6\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.openstack\",\"endpoint\":\"http://cloud.recas.ba.infn.it:5000/v2.0\",\"provider_id\":\"provider-RECAS-BARI\",\"type\":\"compute\"},\"type\":\"service\"}", + "{\"_id\":\"4401ac5dc8cfbbb737b0a02575e81d9b\",\"_rev\":\"2-be00f87438604f04d353233daabc562c\",\"data\":{\"service_type\":\"eu.egi.cloud.vm-management.occi\",\"endpoint\":\"http://onedock.i3m.upv.es:11443\",\"provider_id\":\"provider-UPV-GRyCAP\",\"type\":\"compute\"},\"type\":\"service\"}", + MediaType.APPLICATION_JSON)); + + // Images: Compute service on provider-UPV-GRyCAP + mockServer + .expect(requestTo(baseUrl + + "service/id/4401ac5dc8cfbbb737b0a02575e81d9b/has_many/images?include_docs=true")) + .andExpect(method(HttpMethod.GET)) + .andRespond(withSuccess( + "{\n \"total_rows\": 42,\n \"offset\": 0,\n \"rows\": [\n {\n \"id\": \"7efc59c5db69ea67c5100de0f7236866\",\n \"key\": [\n \"4401ac5dc8cfbbb737b0a02575e81d9b\",\n \"images\"\n ],\n \"value\": {\n \"image_id\": \"1\",\n \"image_name\": \"indigodatacloud/ubuntu-sshd:14.04-devel\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n },\n \"doc\": {\n \"_id\": \"7efc59c5db69ea67c5100de0f7236866\",\n \"_rev\": \"2-105db8faf961d5aa0a215b67942c1821\",\n \"type\": \"image\",\n \"data\": {\n \"image_id\": \"1\",\n \"image_name\": \"indigodatacloud/ubuntu-sshd:14.04-devel\",\n \"architecture\": \"x86_64\",\n \"type\": \"linux\",\n \"distribution\": \"ubuntu\",\n \"version\": \"14.04\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n }\n }\n },\n {\n \"id\": \"7efc59c5db69ea67c5100de0f724f37a\",\n \"key\": [\n \"4401ac5dc8cfbbb737b0a02575e81d9b\",\n \"images\"\n ],\n \"value\": {\n \"image_id\": \"1\",\n \"image_name\": \"image-create-test\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n },\n \"doc\": {\n \"_id\": \"7efc59c5db69ea67c5100de0f724f37a\",\n \"_rev\": \"1-c9bf9d0d3f69738da930d97b8002b2c4\",\n \"type\": \"image\",\n \"data\": {\n \"image_id\": \"1\",\n \"image_name\": \"image-create-test\",\n \"architecture\": \"x86_64\",\n \"type\": \"linux\",\n \"distribution\": \"ubuntu\",\n \"version\": \"14.04\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n }\n }\n },\n {\n \"id\": \"7efc59c5db69ea67c5100de0f72580e9\",\n \"key\": [\n \"4401ac5dc8cfbbb737b0a02575e81d9b\",\n \"images\"\n ],\n \"value\": {\n \"image_id\": \"xxx\",\n \"image_name\": \"image-create-test\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n },\n \"doc\": {\n \"_id\": \"7efc59c5db69ea67c5100de0f72580e9\",\n \"_rev\": \"1-180d402f4985bbd00692937a9bcf717c\",\n \"type\": \"image\",\n \"data\": {\n \"image_id\": \"xxx\",\n \"image_name\": \"image-create-test\",\n \"architecture\": \"x86_64\",\n \"type\": \"linux\",\n \"distribution\": \"ubuntu\",\n \"version\": \"14.04\",\n \"service\": \"4401ac5dc8cfbbb737b0a02575e81d9b\"\n }\n }\n }\n ]\n}", MediaType.APPLICATION_JSON)); } diff --git a/src/test/resources/slam/preferences-indigo-demo.json b/src/test/resources/slam/preferences-indigo-demo.json index 9b90335084..cb7b876041 100644 --- a/src/test/resources/slam/preferences-indigo-demo.json +++ b/src/test/resources/slam/preferences-indigo-demo.json @@ -8,7 +8,7 @@ "priority": [ { "sla_id": "4401ac5dc8cfbbb737b0a02575ee53f6", - "service_id": "4401ac5dc8cfbbb737b0a02575e8040f" + "service_id": "4401ac5dc8cfbbb737b0a02575e81d9b" }, { "sla_id": "4401ac5dc8cfbbb737b0a02575ee3b58", @@ -52,7 +52,7 @@ "services": [ { "type": "compute", - "service_id": "4401ac5dc8cfbbb737b0a02575e8040f", + "service_id": "4401ac5dc8cfbbb737b0a02575e81d9b", "targets": [ { "type": "computing_time", diff --git a/src/test/resources/tosca/galaxy_tosca_clues.yaml b/src/test/resources/tosca/galaxy_tosca_clues.yaml index 17600e5458..ea10aa4471 100644 --- a/src/test/resources/tosca/galaxy_tosca_clues.yaml +++ b/src/test/resources/tosca/galaxy_tosca_clues.yaml @@ -19,6 +19,12 @@ topology_template: - lrms: torque_front_end - wn: wn_node + elastic_cluster_front_end_2: + type: tosca.nodes.indigo.ElasticCluster + requirements: + - lrms: torque_front_end + - wn: wn_node + torque_front_end: type: tosca.nodes.indigo.LRMS.FrontEnd.Torque properties: @@ -51,7 +57,7 @@ topology_template: min_instances: 0 requirements: - host: torque_wn - + torque_wn: type: tosca.nodes.indigo.Compute capabilities: