diff options
Diffstat (limited to 'catalog-model/src/main/java/org')
215 files changed, 52071 insertions, 0 deletions
diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java new file mode 100644 index 0000000000..674681081c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +public class AdditionalInfoParameterInfo implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2066876282722907709L; + + String uniqueId; + String key; + String value; + + public AdditionalInfoParameterInfo() { + super(); + } + + public AdditionalInfoParameterInfo(String key, String value) { + super(); + this.key = key; + this.value = value; + } + + public AdditionalInfoParameterInfo(String uniqueId, String key, String value) { + super(); + this.uniqueId = uniqueId; + this.key = key; + this.value = value; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + @Override + public String toString() { + return "AdditionalInfoParameterInfo [uniqueId=" + uniqueId + ", key=" + key + ", value=" + value + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java new file mode 100644 index 0000000000..9ad0718e71 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; + +public class AdditionalInformationDefinition extends AdditionalInfoParameterDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5266684455492488001L; + + private String parentUniqueId; + + private List<AdditionalInfoParameterInfo> parameters; + + public AdditionalInformationDefinition() { + super(); + } + + public AdditionalInformationDefinition(AdditionalInfoParameterDataDefinition p, String parentUniqueId, + List<AdditionalInfoParameterInfo> parameters) { + super(p); + this.parentUniqueId = parentUniqueId; + this.parameters = parameters; + } + + public AdditionalInformationDefinition(AdditionalInformationDefinition pd) { + this.setUniqueId(pd.getUniqueId()); + this.setCreationTime(pd.getCreationTime()); + this.setModificationTime(pd.getModificationTime()); + this.parentUniqueId = pd.parentUniqueId; + this.parameters = pd.parameters; + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + public List<AdditionalInfoParameterInfo> getParameters() { + return parameters; + } + + public void setParameters(List<AdditionalInfoParameterInfo> parameters) { + this.parameters = parameters; + } + + @Override + public String toString() { + return "AdditionalInformationDefinition [parameters=" + parameters + ", parentUniqueId=" + parentUniqueId + " " + + super.toString() + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java new file mode 100644 index 0000000000..f822e67715 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java @@ -0,0 +1,138 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; + +public class ArtifactDefinition extends ArtifactDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8323923665449071631L; + + /** + * Base64 encoded Artifact file data + */ + private byte[] payloadData; + + private List<HeatParameterDefinition> heatParameters; + + private String generatedFromId; + + public byte[] getPayloadData() { + return payloadData; + } + + public void setPayload(byte[] payloadData) { + this.payloadData = payloadData; + } + + public void setPayloadData(String payloadData) { + if (payloadData != null) { + this.payloadData = payloadData.getBytes(); + } + } + + public ArtifactDefinition() { + super(); + } + + public ArtifactDefinition(ArtifactDataDefinition a) { + super(a); + + } + + public ArtifactDefinition(ArtifactDataDefinition a, String payloadData) { + super(a); + setPayloadData(payloadData); + } + + public List<HeatParameterDefinition> getHeatParameters() { + return heatParameters; + } + + public void setHeatParameters(List<HeatParameterDefinition> properties) { + this.heatParameters = properties; + } + + public String getGeneratedFromId() { + return generatedFromId; + } + + public void setGeneratedFromId(String generatedFromId) { + this.generatedFromId = generatedFromId; + } + + public boolean checkEsIdExist() { + if ((getEsId() != null) && (!getEsId().trim().isEmpty())) { + return true; + } + return false; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((generatedFromId == null) ? 0 : generatedFromId.hashCode()); + result = prime * result + ((heatParameters == null) ? 0 : heatParameters.hashCode()); + result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + ArtifactDefinition other = (ArtifactDefinition) obj; + if (generatedFromId == null) { + if (other.generatedFromId != null) + return false; + } else if (!generatedFromId.equals(other.generatedFromId)) + return false; + if (heatParameters == null) { + if (other.heatParameters != null) + return false; + } else if (heatParameters.size() != other.heatParameters.size()) + return false; + else { + for (HeatParameterDefinition heatParam : heatParameters) { + if (!other.heatParameters.contains(heatParam)) { + return false; + } + } + } + if (payloadData == null) { + if (other.payloadData != null) + return false; + } else if (!payloadData.equals(other.payloadData)) + return false; + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java new file mode 100644 index 0000000000..a761d74016 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class ArtifactType { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + ArtifactType other = (ArtifactType) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java new file mode 100644 index 0000000000..7172ddc35d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class ArtifactUiDownloadData { + + // POJO for UI artifact download, holding artifact filename and base64 + // content + String artifactName; + String base64Contents; + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public void setBase64Contents(String base64Contents) { + this.base64Contents = base64Contents; + } + + public String getArtifactName() { + return artifactName; + } + + public String getBase64Contents() { + return base64Contents; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java new file mode 100644 index 0000000000..120a87c610 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; + +public class AttributeDefinition extends AttributeDataDefinition implements IComplexDefaultValue, Serializable { + + /** + * + */ + private static final long serialVersionUID = -6306111879714097811L; + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((parentUniqueId == null) ? 0 : parentUniqueId.hashCode()); + return result; + } + + /** + * The resource id which this property belongs to + */ + private String parentUniqueId; + + public AttributeDefinition(AttributeDefinition hpdd) { + super(hpdd); + } + + public AttributeDefinition() { + super(); + } + + public AttributeDefinition(AttributeDataDefinition p) { + super(p); + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + @Override + public String toString() { + return super.toString() + " [ parentUniqueId=" + parentUniqueId + "]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java new file mode 100644 index 0000000000..2f9cf48917 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +public class CapReqDef { + Map<String, List<CapabilityDefinition>> capabilities; + Map<String, List<RequirementDefinition>> requirements; + + public CapReqDef() { + super(); + } + + public CapReqDef(Map<String, List<RequirementDefinition>> requirements, + Map<String, List<CapabilityDefinition>> capabilities) { + super(); + this.capabilities = capabilities; + this.requirements = requirements; + } + + public Map<String, List<CapabilityDefinition>> getCapabilities() { + return capabilities; + } + + public Map<String, List<RequirementDefinition>> getRequirements() { + return requirements; + } + + public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) { + this.capabilities = capabilities; + } + + public void setRequirements(Map<String, List<RequirementDefinition>> requirements) { + this.requirements = requirements; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java new file mode 100644 index 0000000000..61ba356aa1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +/** + * Specifies the capabilities that the Node Type exposes. + */ +public class CapabilityDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -3871825415338268030L; + + private String uniqueId; + + private String description; + + private String name; + + /** Identifies the type of the capability. */ + private String type; + + private List<String> validSourceTypes; + + private List<String> capabilitySources; + /** + * The properties field contains all properties defined for + * CapabilityDefinition + */ + private List<ComponentInstanceProperty> properties; + + // specifies the resource instance holding this requirement + private String ownerId; + private String ownerName; + private String minOccurrences; + private String maxOccurrences; + + public CapabilityDefinition() { + super(); + } + + public CapabilityDefinition(CapabilityDefinition other) { + this.uniqueId = other.uniqueId; + this.description = other.description; + this.name = other.name; + this.type = other.type; + if (other.validSourceTypes != null) { + this.validSourceTypes = new ArrayList<>(other.validSourceTypes); + } + if (other.capabilitySources != null) { + this.capabilitySources = new ArrayList<>(other.capabilitySources); + } + if (other.properties != null) { + this.properties = new ArrayList<>(other.properties); + } + this.ownerId = other.ownerId; + this.ownerName = other.ownerName; + this.minOccurrences = other.minOccurrences; + this.maxOccurrences = other.maxOccurrences; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List<String> getValidSourceTypes() { + return validSourceTypes; + } + + public void setValidSourceTypes(List<String> validSourceTypes) { + this.validSourceTypes = validSourceTypes; + } + + public List<String> getCapabilitySources() { + return capabilitySources; + } + + public List<ComponentInstanceProperty> getProperties() { + return properties; + } + + public void setProperties(List<ComponentInstanceProperty> properties) { + this.properties = properties; + } + + public void setCapabilitySources(List<String> capabilitySources) { + this.capabilitySources = capabilitySources; + } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getMinOccurrences() { + return minOccurrences; + } + + public void setMinOccurrences(String minOccurrences) { + this.minOccurrences = minOccurrences; + } + + public String getMaxOccurrences() { + return maxOccurrences; + } + + public void setMaxOccurrences(String maxOccurrences) { + this.maxOccurrences = maxOccurrences; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((capabilitySources == null) ? 0 : capabilitySources.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((maxOccurrences == null) ? 0 : maxOccurrences.hashCode()); + result = prime * result + ((minOccurrences == null) ? 0 : minOccurrences.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode()); + result = prime * result + ((ownerName == null) ? 0 : ownerName.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); + result = prime * result + ((validSourceTypes == null) ? 0 : validSourceTypes.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + CapabilityDefinition other = (CapabilityDefinition) obj; + if (capabilitySources == null) { + if (other.capabilitySources != null) + return false; + } else if (!capabilitySources.equals(other.capabilitySources)) + return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (maxOccurrences == null) { + if (other.maxOccurrences != null) + return false; + } else if (!maxOccurrences.equals(other.maxOccurrences)) + return false; + if (minOccurrences == null) { + if (other.minOccurrences != null) + return false; + } else if (!minOccurrences.equals(other.minOccurrences)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (ownerId == null) { + if (other.ownerId != null) + return false; + } else if (!ownerId.equals(other.ownerId)) + return false; + if (ownerName == null) { + if (other.ownerName != null) + return false; + } else if (!ownerName.equals(other.ownerName)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + if (type == null) { + if (other.type != null) + return false; + } else if (!type.equals(other.type)) + return false; + if (uniqueId == null) { + if (other.uniqueId != null) + return false; + } else if (!uniqueId.equals(other.uniqueId)) + return false; + if (validSourceTypes == null) { + if (other.validSourceTypes != null) + return false; + } else if (!validSourceTypes.equals(other.validSourceTypes)) + return false; + return true; + } + + @Override + public String toString() { + return "CapabilityDefinition [uniqueId=" + uniqueId + ", description=" + description + ", name=" + name + + ", type=" + type + ", validSourceTypes=" + validSourceTypes + ", capabilitySources=" + + capabilitySources + ", properties=" + properties + ", ownerId=" + ownerId + ", ownerName=" + ownerName + + ", minOccurrences=" + minOccurrences + ", maxOccurrences=" + maxOccurrences + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java new file mode 100644 index 0000000000..4291ee746d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.CapabilityTypeDataDefinition; + +/** + * Specifies the capabilities that the Node Type exposes. + */ +public class CapabilityTypeDefinition extends CapabilityTypeDataDefinition { + + private String derivedFrom; + + private Map<String, PropertyDefinition> properties; + + public String getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(String derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public Map<String, PropertyDefinition> getProperties() { + return properties; + } + + public void setProperties(Map<String, PropertyDefinition> properties) { + this.properties = properties; + } + + public CapabilityTypeDefinition() { + super(); + } + + public CapabilityTypeDefinition(CapabilityTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ derivedFrom=" + derivedFrom + ", properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java new file mode 100644 index 0000000000..5e5edf99ac --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +public class CapabiltyInstance { + + private String uniqueId; + + private Map<String, String> properties; + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public Map<String, String> getProperties() { + return properties; + } + + public void setProperties(Map<String, String> properties) { + this.properties = properties; + } + + @Override + public String toString() { + return "CapabiltyInstance [uniqueId=" + uniqueId + ", properties=" + properties + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java new file mode 100644 index 0000000000..03cab66d53 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class Category { + + private String name;// will be changed to categoryDisplayName + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Category other = (Category) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + return true; + } + + @Override + public String toString() { + return "Category [name=" + name + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java new file mode 100644 index 0000000000..57a70de388 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java @@ -0,0 +1,598 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; + +import org.codehaus.jackson.annotate.JsonIgnore; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; + +public abstract class Component implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -6373756459967949120L; + + private ComponentMetadataDefinition componentMetadataDefinition; + private Map<String, ArtifactDefinition> artifacts; + private Map<String, ArtifactDefinition> deploymentArtifacts; + private Map<String, ArtifactDefinition> toscaArtifacts; + + private List<CategoryDefinition> categories; + + // User + private String creatorUserId; + private String creatorFullName; + private String lastUpdaterUserId; + private String lastUpdaterFullName; + + protected ComponentTypeEnum componentType; + + private List<ComponentInstance> componentInstances; + + private List<RequirementCapabilityRelDef> componentInstancesRelations; + + private Map<String, List<ComponentInstanceInput>> componentInstancesInputs; + + private Map<String, List<ComponentInstanceProperty>> componentInstancesProperties; + + private Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes; + + private Map<String, List<CapabilityDefinition>> capabilities; + + private Map<String, List<RequirementDefinition>> requirements; + + private List<InputDefinition> inputs; + + private List<GroupDefinition> groups; + + public Component(ComponentMetadataDefinition componentMetadataDefinition) { + this.componentMetadataDefinition = componentMetadataDefinition; + } + + @JsonIgnore + public ComponentMetadataDefinition getComponentMetadataDefinition() { + return componentMetadataDefinition; + } + + public Map<String, ArtifactDefinition> getArtifacts() { + return artifacts; + } + + public void setArtifacts(Map<String, ArtifactDefinition> artifacts) { + this.artifacts = artifacts; + } + + public Map<String, ArtifactDefinition> getToscaArtifacts() { + return toscaArtifacts; + } + + public void setToscaArtifacts(Map<String, ArtifactDefinition> toscaArtifacts) { + this.toscaArtifacts = toscaArtifacts; + } + + public String getUniqueId() { + return componentMetadataDefinition.getMetadataDataDefinition().getUniqueId(); + } + + public void setUniqueId(String uniqueId) { + componentMetadataDefinition.getMetadataDataDefinition().setUniqueId(uniqueId); + } + + public void setName(String name) { + componentMetadataDefinition.getMetadataDataDefinition().setName(name); + } + + public void setVersion(String version) { + componentMetadataDefinition.getMetadataDataDefinition().setVersion(version); + } + + public void setHighestVersion(Boolean isHighestVersion) { + componentMetadataDefinition.getMetadataDataDefinition().setHighestVersion(isHighestVersion); + } + + public void setCreationDate(Long creationDate) { + componentMetadataDefinition.getMetadataDataDefinition().setCreationDate(creationDate); + } + + public void setLastUpdateDate(Long lastUpdateDate) { + componentMetadataDefinition.getMetadataDataDefinition().setLastUpdateDate(lastUpdateDate); + } + + public void setDescription(String description) { + componentMetadataDefinition.getMetadataDataDefinition().setDescription(description); + } + + public void setState(LifecycleStateEnum state) { + componentMetadataDefinition.getMetadataDataDefinition().setState(state.name()); + } + + public void setTags(List<String> tags) { + componentMetadataDefinition.getMetadataDataDefinition().setTags(tags); + } + + public void setIcon(String icon) { + componentMetadataDefinition.getMetadataDataDefinition().setIcon(icon); + } + + public void setContactId(String contactId) { + componentMetadataDefinition.getMetadataDataDefinition().setContactId(contactId); + } + + public String getCreatorUserId() { + return creatorUserId; + } + + public void setCreatorUserId(String creatorUserId) { + this.creatorUserId = creatorUserId; + } + + public String getCreatorFullName() { + return creatorFullName; + } + + public void setCreatorFullName(String creatorFullName) { + this.creatorFullName = creatorFullName; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public String getName() { + return componentMetadataDefinition.getMetadataDataDefinition().getName(); + } + + public String getVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().getVersion(); + } + + public Boolean isHighestVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().isHighestVersion(); + } + + public Long getCreationDate() { + return componentMetadataDefinition.getMetadataDataDefinition().getCreationDate(); + } + + public Long getLastUpdateDate() { + return componentMetadataDefinition.getMetadataDataDefinition().getLastUpdateDate(); + } + + public String getDescription() { + return componentMetadataDefinition.getMetadataDataDefinition().getDescription(); + } + + public LifecycleStateEnum getLifecycleState() { + if (componentMetadataDefinition.getMetadataDataDefinition().getState() != null) { + return LifecycleStateEnum.valueOf(componentMetadataDefinition.getMetadataDataDefinition().getState()); + } else { + return null; + } + } + + public List<String> getTags() { + return componentMetadataDefinition.getMetadataDataDefinition().getTags(); + } + + public String getIcon() { + return componentMetadataDefinition.getMetadataDataDefinition().getIcon(); + } + + public String getContactId() { + return componentMetadataDefinition.getMetadataDataDefinition().getContactId(); + } + + public List<InputDefinition> getInputs() { + return inputs; + } + + public void setInputs(List<InputDefinition> inputs) { + this.inputs = inputs; + } + + public void setLifecycleState(LifecycleStateEnum state) { + if (state != null) { + this.componentMetadataDefinition.getMetadataDataDefinition().setState(state.name()); + } + } + + public String getUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getUUID(); + } + + public void setUUID(String uUID) { + componentMetadataDefinition.getMetadataDataDefinition().setUUID(uUID); + } + + public void setSystemName(String systemName) { + componentMetadataDefinition.getMetadataDataDefinition().setSystemName(systemName); + } + + public String getSystemName() { + return componentMetadataDefinition.getMetadataDataDefinition().getSystemName(); + } + + public void setAllVersions(Map<String, String> allVersions) { + componentMetadataDefinition.getMetadataDataDefinition().setAllVersions(allVersions); + } + + public Map<String, String> getAllVersions() { + return componentMetadataDefinition.getMetadataDataDefinition().getAllVersions(); + } + + public Map<String, ArtifactDefinition> getDeploymentArtifacts() { + return deploymentArtifacts; + } + + public void setDeploymentArtifacts(Map<String, ArtifactDefinition> deploymentArtifacts) { + this.deploymentArtifacts = deploymentArtifacts; + } + + public List<CategoryDefinition> getCategories() { + return categories; + } + + public void setCategories(List<CategoryDefinition> categories) { + this.categories = categories; + } + + public String getNormalizedName() { + return componentMetadataDefinition.getMetadataDataDefinition().getNormalizedName(); + } + + public void setNormalizedName(String normalizedName) { + componentMetadataDefinition.getMetadataDataDefinition().setNormalizedName(normalizedName); + } + + public ComponentTypeEnum getComponentType() { + return componentType; + } + + public void setComponentType(ComponentTypeEnum componentType) { + this.componentType = componentType; + } + + public Map<String, List<CapabilityDefinition>> getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) { + this.capabilities = capabilities; + } + + public Map<String, List<RequirementDefinition>> getRequirements() { + return requirements; + } + + public void setRequirements(Map<String, List<RequirementDefinition>> requirements) { + this.requirements = requirements; + } + + public List<ComponentInstance> getComponentInstances() { + return componentInstances; + } + + public void setComponentInstances(List<ComponentInstance> resourceInstances) { + this.componentInstances = resourceInstances; + } + + public List<RequirementCapabilityRelDef> getComponentInstancesRelations() { + return componentInstancesRelations; + } + + public void setComponentInstancesRelations(List<RequirementCapabilityRelDef> resourceInstancesRelations) { + this.componentInstancesRelations = resourceInstancesRelations; + } + + public Map<String, List<ComponentInstanceProperty>> getComponentInstancesProperties() { + return componentInstancesProperties; + } + + public void setComponentInstancesProperties( + Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties) { + this.componentInstancesProperties = resourceInstancesProperties; + } + + public Boolean getIsDeleted() { + return componentMetadataDefinition.getMetadataDataDefinition().isDeleted(); + } + + public void setIsDeleted(Boolean isDeleted) { + componentMetadataDefinition.getMetadataDataDefinition().setIsDeleted(isDeleted); + } + + public String getProjectCode() { + return componentMetadataDefinition.getMetadataDataDefinition().getProjectCode(); + } + + public void setProjectCode(String projectCode) { + componentMetadataDefinition.getMetadataDataDefinition().setProjectCode(projectCode); + } + + public String getCsarUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getCsarUUID(); + } + + public void setCsarUUID(String csarUUID) { + componentMetadataDefinition.getMetadataDataDefinition().setCsarUUID(csarUUID); + } + + public String getCsarVersion() { + return componentMetadataDefinition.getMetadataDataDefinition().getCsarVersion(); + } + + public void setCsarVersion(String csarVersion) { + componentMetadataDefinition.getMetadataDataDefinition().setCsarVersion(csarVersion); + } + + public String getImportedToscaChecksum() { + return componentMetadataDefinition.getMetadataDataDefinition().getImportedToscaChecksum(); + } + + public void setImportedToscaChecksum(String importedToscaChecksum) { + componentMetadataDefinition.getMetadataDataDefinition().setImportedToscaChecksum(importedToscaChecksum); + } + + public String getInvariantUUID() { + return componentMetadataDefinition.getMetadataDataDefinition().getInvariantUUID(); + } + + public void setInvariantUUID(String invariantUUID) { + componentMetadataDefinition.getMetadataDataDefinition().setInvariantUUID(invariantUUID); + } + + public List<GroupDefinition> getGroups() { + return groups; + } + + public void setGroups(List<GroupDefinition> groups) { + this.groups = groups; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((artifacts == null) ? 0 : artifacts.hashCode()); + result = prime * result + ((categories == null) ? 0 : categories.hashCode()); + result = prime * result + ((componentMetadataDefinition == null) ? 0 : componentMetadataDefinition.hashCode()); + result = prime * result + ((creatorUserId == null) ? 0 : creatorUserId.hashCode()); + result = prime * result + ((creatorFullName == null) ? 0 : creatorFullName.hashCode()); + result = prime * result + ((deploymentArtifacts == null) ? 0 : deploymentArtifacts.hashCode()); + result = prime * result + ((lastUpdaterUserId == null) ? 0 : lastUpdaterUserId.hashCode()); + result = prime * result + ((lastUpdaterFullName == null) ? 0 : lastUpdaterFullName.hashCode()); + result = prime * result + ((capabilities == null) ? 0 : capabilities.hashCode()); + result = prime * result + ((requirements == null) ? 0 : requirements.hashCode()); + result = prime * result + ((componentInstances == null) ? 0 : componentInstances.hashCode()); + result = prime * result + + ((componentInstancesProperties == null) ? 0 : componentInstancesProperties.hashCode()); + result = prime * result + + ((componentInstancesAttributes == null) ? 0 : componentInstancesAttributes.hashCode()); + result = prime * result + ((componentInstancesInputs == null) ? 0 : componentInstancesInputs.hashCode()); + result = prime * result + ((componentInstancesRelations == null) ? 0 : componentInstancesRelations.hashCode()); + result = prime * result + ((groups == null) ? 0 : groups.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + Component other = (Component) obj; + if (artifacts == null) { + if (other.artifacts != null) + return false; + } else if (!artifacts.equals(other.artifacts)) + return false; + if (categories == null) { + if (other.categories != null) + return false; + } else if (!categories.equals(other.categories)) + return false; + if (componentMetadataDefinition == null) { + if (other.componentMetadataDefinition != null) + return false; + } else if (!componentMetadataDefinition.equals(other.componentMetadataDefinition)) + return false; + if (creatorUserId == null) { + if (other.creatorUserId != null) + return false; + } else if (!creatorUserId.equals(other.creatorUserId)) + return false; + if (creatorFullName == null) { + if (other.creatorFullName != null) + return false; + } else if (!creatorFullName.equals(other.creatorFullName)) + return false; + if (deploymentArtifacts == null) { + if (other.deploymentArtifacts != null) + return false; + } else if (!deploymentArtifacts.equals(other.deploymentArtifacts)) + return false; + if (lastUpdaterUserId == null) { + if (other.lastUpdaterUserId != null) + return false; + } else if (!lastUpdaterUserId.equals(other.lastUpdaterUserId)) + return false; + if (lastUpdaterFullName == null) { + if (other.lastUpdaterFullName != null) + return false; + } else if (!lastUpdaterFullName.equals(other.lastUpdaterFullName)) + return false; + if (componentInstances == null) { + if (other.componentInstances != null) + return false; + } else if (!componentInstances.equals(other.componentInstances)) + return false; + if (componentInstancesProperties == null) { + if (other.componentInstancesProperties != null) + return false; + } else if (!componentInstancesProperties.equals(other.componentInstancesProperties)) + return false; + + if (!Objects.equals(componentInstancesAttributes, other.componentInstancesAttributes)) { + return false; + } + if (!Objects.equals(componentInstancesInputs, other.componentInstancesInputs)) { + return false; + } + if (componentInstancesRelations == null) { + if (other.componentInstancesRelations != null) + return false; + } else if (!componentInstancesRelations.equals(other.componentInstancesRelations)) + return false; + if (requirements == null) { + if (other.requirements != null) + return false; + } else if (!requirements.equals(other.requirements)) + return false; + if (capabilities == null) { + if (other.capabilities != null) + return false; + } else if (!capabilities.equals(other.capabilities)) + return false; + if (groups == null) { + if (other.groups != null) + return false; + } else if (!groups.equals(other.groups)) + return false; + return true; + } + + public void addCategory(String category, String subCategory) { + if (category != null || subCategory != null) { + if (categories == null) { + categories = new ArrayList<>(); + } + CategoryDefinition selectedCategory = null; + for (CategoryDefinition categoryDef : categories) { + if (categoryDef.getName().equals(category)) { + selectedCategory = categoryDef; + } + } + if (selectedCategory == null) { + selectedCategory = new CategoryDefinition(); + selectedCategory.setName(category); + categories.add(selectedCategory); + } + List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories(); + if (subcategories == null) { + subcategories = new ArrayList<>(); + selectedCategory.setSubcategories(subcategories); + } + SubCategoryDefinition selectedSubcategory = null; + for (SubCategoryDefinition subcategory : subcategories) { + if (subcategory.getName().equals(subCategory)) { + selectedSubcategory = subcategory; + } + } + if (selectedSubcategory == null) { + selectedSubcategory = new SubCategoryDefinition(); + selectedSubcategory.setName(subCategory); + subcategories.add(selectedSubcategory); + } + } + } + + public void addCategory(CategoryDefinition category) { + addCategory(category, null); + } + + public void addCategory(CategoryDefinition category, SubCategoryDefinition subCategory) { + if (categories == null) { + categories = new ArrayList<>(); + } + boolean foundCat = false; + for (CategoryDefinition cat : categories) { + if (cat.getName().equals(category.getName())) { + foundCat = true; + if (subCategory != null) { + List<SubCategoryDefinition> subcategories = cat.getSubcategories(); + if (subcategories == null) { + subcategories = new ArrayList<>(); + cat.setSubcategories(subcategories); + } + for (SubCategoryDefinition subcat : subcategories) { + boolean foundSub = false; + if (subcat.getName().equals(subCategory.getName())) { + foundSub = true; + } + if (foundSub == false) { + subcategories.add(subCategory); + break; + } + } + } + } + } + if (foundCat == false) { + if (subCategory != null) { + category.addSubCategory(subCategory); + } + categories.add(category); + } + } + + public Map<String, List<ComponentInstanceAttribute>> getComponentInstancesAttributes() { + return componentInstancesAttributes; + } + + public void setComponentInstancesAttributes( + Map<String, List<ComponentInstanceAttribute>> componentInstancesAttributes) { + this.componentInstancesAttributes = componentInstancesAttributes; + } + + public Map<String, List<ComponentInstanceInput>> getComponentInstancesInputs() { + return componentInstancesInputs; + } + + public void setComponentInstancesInputs(Map<String, List<ComponentInstanceInput>> componentInstancesInputs) { + this.componentInstancesInputs = componentInstancesInputs; + } + + public void setSpecificComponetTypeArtifacts(Map<String, ArtifactDefinition> specificComponentTypeArtifacts) { + // Implement where needed + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java new file mode 100644 index 0000000000..ce9ac67ced --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +public class ComponentInstInputsMap { + + Map<String, List<InputDefinition>> componentInstanceInputsMap; + + public Map<String, List<InputDefinition>> getComponentInstanceInputsMap() { + return componentInstanceInputsMap; + } + + public void setComponentInstanceInputsMap(Map<String, List<InputDefinition>> componentInstanceInputsMap) { + this.componentInstanceInputsMap = componentInstanceInputsMap; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java new file mode 100644 index 0000000000..baaf89bcfc --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; + +public class ComponentInstance extends ComponentInstanceDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6721465693884621223L; + + private String icon; + + private String componentName; + private String componentVersion; + private String toscaComponentName; + private Map<String, List<CapabilityDefinition>> capabilities; + private Map<String, List<RequirementDefinition>> requirements; + private Map<String, ArtifactDefinition> deploymentArtifacts; + + public ComponentInstance() { + super(); + } + + public ComponentInstance(ComponentInstanceDataDefinition r) { + super(r); + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getComponentName() { + return componentName; + } + + public void setComponentName(String resourceName) { + this.componentName = resourceName; + } + + public String getComponentVersion() { + return componentVersion; + } + + public String getToscaComponentName() { + return toscaComponentName; + } + + public void setToscaComponentName(String toscaComponentName) { + this.toscaComponentName = toscaComponentName; + } + + public void setComponentVersion(String resourceVersion) { + this.componentVersion = resourceVersion; + } + + public Map<String, List<CapabilityDefinition>> getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map<String, List<CapabilityDefinition>> capabilities) { + this.capabilities = capabilities; + } + + public Map<String, List<RequirementDefinition>> getRequirements() { + return requirements; + } + + public void setRequirements(Map<String, List<RequirementDefinition>> requirements) { + this.requirements = requirements; + } + + public Map<String, ArtifactDefinition> getDeploymentArtifacts() { + return deploymentArtifacts; + } + + public void setDeploymentArtifacts(Map<String, ArtifactDefinition> deploymentArtifacts) { + this.deploymentArtifacts = deploymentArtifacts; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java new file mode 100644 index 0000000000..12233e733c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +public class ComponentInstanceAttribute extends AttributeDefinition + implements IComponentInstanceConnectedElement, Serializable { + + /** + * + */ + private static final long serialVersionUID = -496828411269235795L; + + private Boolean hidden; + + /** + * The unique id of the attribute value on graph + */ + private String valueUniqueUid; + + public ComponentInstanceAttribute() { + super(); + } + + public ComponentInstanceAttribute(AttributeDefinition pd, Boolean hidden, String valueUniqueUid) { + super(pd); + + this.hidden = hidden; + this.valueUniqueUid = valueUniqueUid; + setParentUniqueId(pd.getParentUniqueId()); + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + @Override + public String toString() { + return "ComponentInstanceAttribute [ " + super.toString() + " , value=" + hidden + ", valueUniqueUid = " + + valueUniqueUid + " ]"; + } + + public Boolean isHidden() { + return hidden; + } + + public void setHidden(Boolean hidden) { + this.hidden = hidden; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java new file mode 100644 index 0000000000..1334fa8c06 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; + +public class ComponentInstanceInput extends InputDefinition implements IComponentInstanceConnectedElement { + + /** + * Value of property + */ + private String value; + + /** + * The unique id of the property value on graph + */ + private String valueUniqueUid; + + private String inputId; + + private List<String> path = null; + + private List<PropertyRule> rules = null; + private String componentInstanceName; + private String componentInstanceId; + + public ComponentInstanceInput() { + super(); + } + + public ComponentInstanceInput(PropertyDataDefinition curPropertyDef, String inputId, String value, + String valueUniqueUid) { + super(curPropertyDef); + this.inputId = inputId; + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public ComponentInstanceInput(InputDefinition pd, String value, String valueUniqueUid) { + super(pd); + + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public String getComponentInstanceName() { + return componentInstanceName; + } + + public void setComponentInstanceName(String componentInstanceName) { + this.componentInstanceName = componentInstanceName; + } + + public String getComponentInstanceId() { + return componentInstanceId; + } + + public void setComponentInstanceId(String componentInstanceId) { + this.componentInstanceId = componentInstanceId; + } + + public String getInputId() { + return inputId; + } + + public void setInputId(String inputId) { + this.inputId = inputId; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + public boolean isDefinition() { + return definition; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public List<String> getPath() { + return path; + } + + public void setPath(List<String> path) { + this.path = path; + } + + public List<PropertyRule> getRules() { + return rules; + } + + public void setRules(List<PropertyRule> rules) { + this.rules = rules; + } + + @Override + public String toString() { + return "ComponentInstanceInput [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java new file mode 100644 index 0000000000..a804170c75 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; + +public class ComponentInstanceProperty extends PropertyDefinition + implements IComponentInstanceConnectedElement, Serializable { + + /** + * + */ + private static final long serialVersionUID = -6559573536869242691L; + + /** + * Value of property + */ + private String value; + + /** + * The unique id of the property value on graph + */ + private String valueUniqueUid; + + private List<String> path = null; + + private List<PropertyRule> rules = null; + + private List<GetInputValueInfo> getInputValues; + + public ComponentInstanceProperty() { + super(); + } + + public ComponentInstanceProperty(PropertyDefinition pd, String value, String valueUniqueUid) { + super(pd); + + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + public boolean isDefinition() { + return definition; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public List<String> getPath() { + return path; + } + + public void setPath(List<String> path) { + this.path = path; + } + + public List<PropertyRule> getRules() { + return rules; + } + + public void setRules(List<PropertyRule> rules) { + this.rules = rules; + } + + public List<GetInputValueInfo> getGetInputValues() { + return getInputValues; + } + + public void setGetInputValues(List<GetInputValueInfo> getInputValues) { + this.getInputValues = getInputValues; + } + + @Override + public String toString() { + return "ComponentInstanceProperty [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + + valueUniqueUid + " , rules=" + rules + " , path=" + path + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java new file mode 100644 index 0000000000..da3947b42f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; + +public class ComponentMetadataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 3570763790267255590L; + + protected ComponentMetadataDataDefinition componentMetadataDataDefinition; + + public ComponentMetadataDefinition() { + + } + + public ComponentMetadataDefinition(ComponentMetadataDataDefinition component) { + this.componentMetadataDataDefinition = component; + } + + public ComponentMetadataDataDefinition getMetadataDataDefinition() { + return this.componentMetadataDataDefinition; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + + ((componentMetadataDataDefinition == null) ? 0 : componentMetadataDataDefinition.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + ComponentMetadataDefinition other = (ComponentMetadataDefinition) obj; + if (componentMetadataDataDefinition == null) { + if (other.componentMetadataDataDefinition != null) + return false; + } else if (!componentMetadataDataDefinition.equals(other.componentMetadataDataDefinition)) + return false; + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java new file mode 100644 index 0000000000..0227de5b50 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java @@ -0,0 +1,316 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class ComponentParametersView { + + boolean ignoreUsers = false; + boolean ignoreGroups = false; + boolean ignoreComponentInstances = false; + boolean ignoreComponentInstancesProperties = false; + boolean ignoreProperties = false; + boolean ignoreCapabilities = false; + boolean ignoreRequirements = false; + boolean ignoreCategories = false; + boolean ignoreAllVersions = false; + boolean ignoreAdditionalInformation = false; + boolean ignoreArtifacts = false; + boolean ignoreInterfaces = false; + boolean ignoreDerivedFrom = false; + boolean ignoreAttributesFrom = false; + boolean ignoreComponentInstancesAttributesFrom = false; + boolean ignoreInputs = false; + boolean ignoreComponentInstancesInputs = false; + + /////////////////////////////////////////////////////////////// + // When adding new member, please update the filter method. + /////////////////////////////////////////////////////////////// + + public Component filter(Component component, ComponentTypeEnum componentType) { + + if (ignoreUsers) { + component.setCreatorUserId(null); + component.setCreatorFullName(null); + component.setLastUpdaterUserId(null); + component.setLastUpdaterFullName(null); + } + + if (ignoreGroups) { + component.setGroups(null); + } + + if (ignoreComponentInstances) { + component.setComponentInstances(null); + component.setComponentInstancesRelations(null); + } + + if (ignoreComponentInstancesProperties) { + component.setComponentInstancesProperties(null); + } + + if (ignoreProperties) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setProperties(null); + break; + default: + break; + } + } + + if (ignoreCapabilities) { + component.setCapabilities(null); + } + + if (ignoreRequirements) { + component.setRequirements(null); + } + + if (ignoreCategories) { + component.setCategories(null); + } + + if (ignoreAllVersions) { + component.setAllVersions(null); + } + + if (ignoreAdditionalInformation) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setAdditionalInformation(null); + break; + default: + break; + } + } + + if (ignoreArtifacts) { + component.setArtifacts(null); + component.setSpecificComponetTypeArtifacts(null); + component.setDeploymentArtifacts(null); + component.setToscaArtifacts(null); + } + + if (ignoreInterfaces) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setInterfaces(null); + break; + default: + break; + } + } + + if (ignoreDerivedFrom) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setDerivedFrom(null); + break; + default: + break; + } + } + + if (ignoreAttributesFrom) { + switch (componentType) { + case RESOURCE: + ((Resource) component).setAttributes(null); + break; + default: + break; + } + } + + if (ignoreComponentInstancesAttributesFrom) { + component.setComponentInstancesAttributes(null); + } + + if (ignoreInputs) { + component.setInputs(null); + } + + if (ignoreComponentInstancesInputs) { + component.setComponentInstancesInputs(null); + } + + return component; + + } + + public void disableAll() { + ignoreUsers = true; + ignoreGroups = true; + ignoreComponentInstances = true; + ignoreComponentInstancesProperties = true; + ignoreProperties = true; + ignoreCapabilities = true; + ignoreRequirements = true; + ignoreCategories = true; + ignoreAllVersions = true; + ignoreAdditionalInformation = true; + ignoreArtifacts = true; + ignoreInterfaces = true; + ignoreDerivedFrom = true; + ignoreAttributesFrom = true; + ignoreInputs = true; + ignoreComponentInstancesAttributesFrom = true; + ignoreComponentInstancesInputs = true; + } + + public boolean isIgnoreGroups() { + return ignoreGroups; + } + + public void setIgnoreGroups(boolean ignoreGroups) { + this.ignoreGroups = ignoreGroups; + } + + public boolean isIgnoreComponentInstances() { + return ignoreComponentInstances; + } + + public void setIgnoreComponentInstances(boolean ignoreComponentInstances) { + this.ignoreComponentInstances = ignoreComponentInstances; + } + + public boolean isIgnoreProperties() { + return ignoreProperties; + } + + public void setIgnoreProperties(boolean ignoreProperties) { + this.ignoreProperties = ignoreProperties; + } + + public boolean isIgnoreCapabilities() { + return ignoreCapabilities; + } + + public void setIgnoreCapabilities(boolean ignoreCapabilities) { + this.ignoreCapabilities = ignoreCapabilities; + } + + public boolean isIgnoreRequirements() { + return ignoreRequirements; + } + + public void setIgnoreRequirements(boolean ignoreRequirements) { + this.ignoreRequirements = ignoreRequirements; + } + + public boolean isIgnoreCategories() { + return ignoreCategories; + } + + public void setIgnoreCategories(boolean ignoreCategories) { + this.ignoreCategories = ignoreCategories; + } + + public boolean isIgnoreAllVersions() { + return ignoreAllVersions; + } + + public void setIgnoreAllVersions(boolean ignoreAllVersions) { + this.ignoreAllVersions = ignoreAllVersions; + } + + public boolean isIgnoreAdditionalInformation() { + return ignoreAdditionalInformation; + } + + public void setIgnoreAdditionalInformation(boolean ignoreAdditionalInformation) { + this.ignoreAdditionalInformation = ignoreAdditionalInformation; + } + + public boolean isIgnoreArtifacts() { + return ignoreArtifacts; + } + + public void setIgnoreArtifacts(boolean ignoreArtifacts) { + this.ignoreArtifacts = ignoreArtifacts; + } + + public boolean isIgnoreComponentInstancesProperties() { + return ignoreComponentInstancesProperties; + } + + public void setIgnoreComponentInstancesProperties(boolean ignoreComponentInstancesProperties) { + this.ignoreComponentInstancesProperties = ignoreComponentInstancesProperties; + } + + public boolean isIgnoreComponentInstancesInputs() { + return ignoreComponentInstancesInputs; + } + + public void setIgnoreComponentInstancesInputs(boolean ignoreComponentInstancesInputs) { + this.ignoreComponentInstancesInputs = ignoreComponentInstancesInputs; + } + + public boolean isIgnoreInterfaces() { + return ignoreInterfaces; + } + + public void setIgnoreInterfaces(boolean ignoreInterfaces) { + this.ignoreInterfaces = ignoreInterfaces; + } + + public boolean isIgnoreAttributesFrom() { + return ignoreAttributesFrom; + } + + public void setIgnoreAttributesFrom(boolean ignoreAttributesFrom) { + this.ignoreAttributesFrom = ignoreDerivedFrom; + } + + public boolean isIgnoreComponentInstancesAttributesFrom() { + return ignoreComponentInstancesAttributesFrom; + } + + public void setIgnoreComponentInstancesAttributesFrom(boolean ignoreComponentInstancesAttributesFrom) { + this.ignoreComponentInstancesAttributesFrom = ignoreComponentInstancesAttributesFrom; + } + + public boolean isIgnoreDerivedFrom() { + return ignoreDerivedFrom; + } + + public void setIgnoreDerivedFrom(boolean ignoreDerivedFrom) { + this.ignoreDerivedFrom = ignoreDerivedFrom; + } + + public boolean isIgnoreUsers() { + return ignoreUsers; + } + + public void setIgnoreUsers(boolean ignoreUsers) { + this.ignoreUsers = ignoreUsers; + } + + public boolean isIgnoreInputs() { + return ignoreInputs; + } + + public void setIgnoreInputs(boolean ignoreInputs) { + this.ignoreInputs = ignoreInputs; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java new file mode 100644 index 0000000000..eef455cbe2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; + +public class ConsumerDefinition extends ConsumerDataDefinition { + + public ConsumerDefinition() { + super(); + } + + public ConsumerDefinition(ConsumerDataDefinition a) { + super(a); + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java new file mode 100644 index 0000000000..972884682e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.DataTypeDataDefinition; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class DataTypeDefinition extends DataTypeDataDefinition { + + // @JsonIgnore + // @org.codehaus.jackson.annotate.JsonIgnore + private DataTypeDefinition derivedFrom; + + private List<PropertyConstraint> constraints; + + private List<PropertyDefinition> properties; + + public DataTypeDefinition() { + super(); + } + + public DataTypeDefinition(DataTypeDataDefinition p) { + super(p); + } + + public DataTypeDefinition(DataTypeDefinition pd) { + this.setName(pd.getName()); + this.setDerivedFrom(pd.getDerivedFrom()); + this.setDerivedFromName(pd.getDerivedFromName()); + this.setUniqueId(pd.getUniqueId()); + this.setConstraints(pd.getConstraints()); + this.setDescription(pd.getDescription()); + } + + public List<PropertyConstraint> getConstraints() { + return constraints; + } + + public void setConstraints(List<PropertyConstraint> constraints) { + this.constraints = constraints; + } + + public DataTypeDefinition getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(DataTypeDefinition derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public List<PropertyDefinition> getProperties() { + return properties; + } + + public void setProperties(List<PropertyDefinition> properties) { + this.properties = properties; + } + + @Override + public String toString() { + return super.toString() + " DataTypeDefinition [derivedFrom=" + derivedFrom + ", constraints=" + constraints + + ", properties=" + properties + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java new file mode 100644 index 0000000000..89b5bfff31 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public enum DistributionStatusEnum { + DISTRIBUTION_NOT_APPROVED("Distribution not approved"), + DISTRIBUTION_APPROVED("Distribution approved"), + DISTRIBUTED("Distributed"), + DISTRIBUTION_REJECTED("Distribution rejected"); + + private String value; + + private DistributionStatusEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + + public static DistributionStatusEnum findState(String state) { + + for (DistributionStatusEnum distributionStatus : DistributionStatusEnum.values()) { + if (distributionStatus.name().equalsIgnoreCase(state) + || distributionStatus.getValue().equalsIgnoreCase(state)) { + return distributionStatus; + } + } + return null; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java new file mode 100644 index 0000000000..05f69f3166 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public enum DistributionTransitionEnum { + APPROVE("approve"), REJECT("reject"); + + String displayName; + + private DistributionTransitionEnum(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + + public static DistributionTransitionEnum getFromDisplayName(String name) { + + for (DistributionTransitionEnum val : DistributionTransitionEnum.values()) { + if (name.equalsIgnoreCase(val.getDisplayName())) { + return val; + } + } + return null; + } + + public static String valuesAsString() { + StringBuilder sb = new StringBuilder(); + for (DistributionTransitionEnum op : DistributionTransitionEnum.values()) { + sb.append(op.getDisplayName()).append(" "); + } + return sb.toString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java new file mode 100644 index 0000000000..5aa3b85d02 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class FunctionalMenuInfo { + + private String functionalMenu; + + public FunctionalMenuInfo() { + super(); + } + + public String getFunctionalMenu() { + return functionalMenu; + } + + public void setFunctionalMenu(String functionalMenu) { + this.functionalMenu = functionalMenu; + } + + @Override + public String toString() { + return "FunctionalMenuInfo [functionalMenu=" + functionalMenu + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java new file mode 100644 index 0000000000..bb53e13251 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class GetInputValueInfo { + String propName; + String inputName; + Integer indexValue; + GetInputValueInfo getInputIndex; + + boolean isList = false; + + public String getPropName() { + return propName; + } + + public void setPropName(String propName) { + this.propName = propName; + } + + public String getInputName() { + return inputName; + } + + public void setInputName(String inputName) { + this.inputName = inputName; + } + + public Integer getIndexValue() { + return indexValue; + } + + public void setIndexValue(Integer indexValue) { + this.indexValue = indexValue; + } + + public GetInputValueInfo getGetInputIndex() { + return getInputIndex; + } + + public void setGetInputIndex(GetInputValueInfo getInputIndex) { + this.getInputIndex = getInputIndex; + } + + public boolean isList() { + return isList; + } + + public void setList(boolean isList) { + this.isList = isList; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java new file mode 100644 index 0000000000..5520e89032 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; + +public class GroupDefinition extends GroupDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -852613634651112247L; + + // map of componentInstances <name: uniqueId> + private Map<String, String> members; + + // properties (properties should be defined in the group type, the + // properties here are actually the value for the properties) + private List<GroupProperty> properties; + + // artifacts - list of artifact uid. All artifacts in the group must already + // be uploaded to the VF + private List<String> artifacts; + + private List<String> artifactsUuid; + + // The unique id of the type of this group + private String typeUid; + + public GroupDefinition() { + super(); + } + + public GroupDefinition(GroupDataDefinition other) { + super(other); + } + + public GroupDefinition(GroupDefinition other) { + this.setName(other.getName()); + this.setUniqueId(other.getUniqueId()); + this.setType(other.getType()); + this.setVersion(other.getVersion()); + this.setInvariantUUID(other.getInvariantUUID()); + this.setGroupUUID(other.getGroupUUID()); + this.setDescription(other.getDescription()); + if (other.members != null) { + this.members = new HashMap<String, String>(other.getMembers()); + } + if (other.properties != null) { + this.properties = other.properties.stream().map(p -> new GroupProperty(p)).collect(Collectors.toList()); + } + if (other.artifacts != null) { + this.artifacts = new ArrayList<String>(other.getArtifacts()); + } + + if (other.artifactsUuid != null) { + this.artifactsUuid = new ArrayList<String>(other.getArtifactsUuid()); + } + this.setTypeUid(other.typeUid); + } + + public Map<String, String> getMembers() { + return members; + } + + public void setMembers(Map<String, String> members) { + this.members = members; + } + + public List<GroupProperty> getProperties() { + return properties; + } + + public void setProperties(List<GroupProperty> properties) { + this.properties = properties; + } + + public List<String> getArtifacts() { + return artifacts; + } + + public void setArtifacts(List<String> artifacts) { + this.artifacts = artifacts; + } + + public String getTypeUid() { + return typeUid; + } + + public void setTypeUid(String typeUid) { + this.typeUid = typeUid; + } + + public List<String> getArtifactsUuid() { + return artifactsUuid; + } + + public void setArtifactsUuid(List<String> artifactsUuid) { + this.artifactsUuid = artifactsUuid; + } + + @Override + public String toString() { + return "GroupDefinition [" + super.toString() + "members=" + members + ", properties=" + properties + + ", artifacts=" + artifacts + ", artifactsUUID=" + artifactsUuid + ", typeUid=" + typeUid + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java new file mode 100644 index 0000000000..cf0afde8e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class GroupProperty extends PropertyDefinition { + + /** + * current value + */ + private String value; + + /** + * The unique is of Group property on graph. If it is null, then the + * property's value was not updated. The value is taken from the group type + * property. + */ + private String valueUniqueUid; + + public GroupProperty() { + super(); + } + + public GroupProperty(PropertyDefinition pd, String value, String valueUniqueUid) { + super(pd); + this.value = value; + this.valueUniqueUid = valueUniqueUid; + } + + public GroupProperty(GroupProperty other) { + super(other); + if (other != null) { + this.value = other.getValue(); + this.valueUniqueUid = other.getValueUniqueUid(); + } + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getValueUniqueUid() { + return valueUniqueUid; + } + + public void setValueUniqueUid(String valueUniqueUid) { + this.valueUniqueUid = valueUniqueUid; + } + + @Override + public String toString() { + return "GroupProperty [ " + super.toString() + " , value=" + value + ", valueUniqueUid = " + valueUniqueUid + + " ]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java new file mode 100644 index 0000000000..cd7fd6401b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition; + +/** + * Specifies the group type that the Node Type exposes. + */ +public class GroupTypeDefinition extends GroupTypeDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -1597773317924162703L; + + private List<PropertyDefinition> properties; + + public List<PropertyDefinition> getProperties() { + return properties; + } + + public void setProperties(List<PropertyDefinition> properties) { + this.properties = properties; + } + + public GroupTypeDefinition() { + super(); + } + + public GroupTypeDefinition(GroupTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java new file mode 100644 index 0000000000..8e03361027 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +import org.openecomp.sdc.be.datatypes.elements.HeatParameterDataDefinition; + +public class HeatParameterDefinition extends HeatParameterDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 3400360721469962105L; + + public HeatParameterDefinition(HeatParameterDataDefinition hpdd) { + super(hpdd); + } + + public HeatParameterDefinition() { + super(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java new file mode 100644 index 0000000000..3d21e07408 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; + +public interface IComplexDefaultValue { + String getType(); + + String getName(); + + String getDefaultValue(); + + void setDefaultValue(String value); + + SchemaDefinition getSchema(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java new file mode 100644 index 0000000000..86de3a1584 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public interface IComponentInstanceConnectedElement { + String getUniqueId(); + + String getValueUniqueUid(); + + void setValueUniqueUid(String value); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java new file mode 100644 index 0000000000..1419353189 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +/** + * An operation parameter can be either a PropertyValue (value or expression) or + * a PropertyDefinition. + */ +public interface IOperationParameter { + /** + * Allow to know if the operation parameter is a property definition or a + * property value. Only parameter exposed as property definitions can be + * used for "custom" operations. + * + * @return true if the operation parameter is a property definition and + * false if the parameter is a property value. + */ + boolean isDefinition(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java new file mode 100644 index 0000000000..fb5943e1bd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java @@ -0,0 +1,67 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +/** + * Specifies an implementation artifact for interfaces or operations of a + * {@link NodeType node type} or {@link RelationshipType relation type}. + * + * @author esofer + */ +public class ImplementationArtifact { + /** + * <p> + * Specifies the type of this artifact. + * </p> + */ + private String artifactType; + + /** + * <p> + * Identifies an Artifact Template to be used as implementation artifact. + * This Artifact Template can be defined in the same Definitions document or + * in a separate, imported document. + * </p> + * + * <p> + * The type of Artifact Template referenced by the artifactRef attribute + * MUST be the same type or a sub-type of the type specified in the + * artifactType attribute. + * </p> + * + * <p> + * Note: if no Artifact Template is referenced, the artifact type specific + * content of the ImplementationArtifact element alone is assumed to + * represent the actual artifact. For example, a simple script could be + * defined in place within the ImplementationArtifact element. + * </p> + */ + private String artifactRef; + + /** + * The name of the archive in which the artifact lies. + */ + private String archiveName; + /** + * The version of the archive in which the artifact lies. + */ + private String archiveVersion; +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java new file mode 100644 index 0000000000..3090d7232e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +public class InputDefinition extends PropertyDefinition { + String label; + Boolean hidden; + Boolean immutable; + List<ComponentInstanceInput> inputsValue; + List<ComponentInstanceProperty> properties; + + public InputDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public InputDefinition(PropertyDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + public InputDefinition(PropertyDefinition pd) { + super(pd); + // TODO Auto-generated constructor stub + } + + public Boolean isHidden() { + return hidden; + } + + public void setHidden(Boolean hidden) { + this.hidden = hidden; + } + + public Boolean isImmutable() { + return immutable; + } + + public void setImmutable(Boolean immutable) { + this.immutable = immutable; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public List<ComponentInstanceInput> getInputsValue() { + return inputsValue; + } + + public void setInputsValue(List<ComponentInstanceInput> inputsValue) { + this.inputsValue = inputsValue; + } + + public List<ComponentInstanceProperty> getProperties() { + return properties; + } + + public void setProperties(List<ComponentInstanceProperty> properties) { + this.properties = properties; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java new file mode 100644 index 0000000000..51ad31199a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; + +/** + * Definition of the operations that can be performed on (instances of) a Node + * Type. + * + * @author esofer + */ +public class InterfaceDefinition extends InterfaceDataDefinition implements IOperationParameter, Serializable { + + /** + * + */ + private static final long serialVersionUID = 8220887972866354746L; + + /** + * Defines an operation available to manage particular aspects of the Node + * Type. + */ + private Map<String, Operation> operations = new HashMap<String, Operation>(); + + private boolean definition; + + public InterfaceDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public InterfaceDefinition(String type, String description, Map<String, Operation> operations) { + super(type, description); + this.operations = operations; + + } + + public InterfaceDefinition(InterfaceDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public Map<String, Operation> getOperations() { + return operations; + } + + public void setOperations(Map<String, Operation> operations) { + this.operations = operations; + } + + @Override + public String toString() { + return "InterfaceDefinition [operations=" + operations + ", definition=" + definition + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java new file mode 100644 index 0000000000..7d135c5f8e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public enum LifeCycleTransitionEnum { + + CHECKOUT("checkout"), + CHECKIN("checkin"), + CERTIFICATION_REQUEST("certificationRequest"), + UNDO_CHECKOUT("undoCheckout"), + CANCEL_CERTIFICATION("cancelCertification"), + START_CERTIFICATION("startCertification"), + FAIL_CERTIFICATION("failCertification"), + CERTIFY("certify"), + DISTRIBUTE("distribute"); + + String displayName; + + private LifeCycleTransitionEnum(String displayName) { + this.displayName = displayName; + } + + public String getDisplayName() { + return displayName; + } + + public static LifeCycleTransitionEnum getFromDisplayName(String name) { + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKOUT.getDisplayName())) { + return LifeCycleTransitionEnum.CHECKOUT; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CHECKIN.getDisplayName())) { + return LifeCycleTransitionEnum.CHECKIN; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFICATION_REQUEST.getDisplayName())) { + return LifeCycleTransitionEnum.CERTIFICATION_REQUEST; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.UNDO_CHECKOUT.getDisplayName())) { + return LifeCycleTransitionEnum.UNDO_CHECKOUT; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CANCEL_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.CANCEL_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.START_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.START_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.FAIL_CERTIFICATION.getDisplayName())) { + return LifeCycleTransitionEnum.FAIL_CERTIFICATION; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.CERTIFY.getDisplayName())) { + return LifeCycleTransitionEnum.CERTIFY; + } + if (name.equalsIgnoreCase(LifeCycleTransitionEnum.DISTRIBUTE.getDisplayName())) { + return LifeCycleTransitionEnum.DISTRIBUTE; + } else + throw new IllegalArgumentException(name + " value does not match any of LifeCycleTransitionEnum values"); + } + + public static String valuesAsString() { + StringBuilder sb = new StringBuilder(); + for (LifeCycleTransitionEnum op : LifeCycleTransitionEnum.values()) { + sb.append(op.getDisplayName()).append(" "); + } + return sb.toString(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java new file mode 100644 index 0000000000..4d9ef81452 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public enum LifecycleStateEnum { + + READY_FOR_CERTIFICATION, + + CERTIFICATION_IN_PROGRESS, + + CERTIFIED, + + NOT_CERTIFIED_CHECKIN, + + NOT_CERTIFIED_CHECKOUT; + + public static LifecycleStateEnum findState(String state) { + + for (LifecycleStateEnum lifecycleStateEnum : LifecycleStateEnum.values()) { + if (lifecycleStateEnum.name().equals(state)) { + return lifecycleStateEnum; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java new file mode 100644 index 0000000000..a793c68528 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.InputsValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; + +/** + * Defines an operation available to manage particular aspects of the Node Type. + * + * @author esofer + */ +public class Operation extends OperationDataDefinition implements IOperationParameter { + + /** Implementation artifact for the interface. */ + private ArtifactDefinition implementation; + + /** + * This OPTIONAL property contains a list of one or more input parameter + * definitions. + */ + // @JsonDeserialize(contentUsing = OperationParameterDeserializer.class) + private Map<String, PropertyValueDefinition> inputs; + + private boolean definition; + + /** + * <p> + * Jackson DeSerialization workaround constructor to create an operation + * with no arguments. + * </p> + * + * @param emptyString + * The empty string provided by jackson. + */ + public Operation() { + super(); + // TODO Auto-generated constructor stub + } + + public Operation(OperationDataDefinition p) { + super(p); + // TODO Auto-generated constructor stub + } + + public Operation(ArtifactDataDefinition implementation, String description, + Map<String, InputsValueDataDefinition> inputs) { + super(description); + + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + public ArtifactDefinition getImplementation() { + return implementation; + } + + public void setImplementation(ArtifactDefinition implementation) { + this.implementation = implementation; + } + + public Map<String, PropertyValueDefinition> getInputs() { + return inputs; + } + + public void setInputs(Map<String, PropertyValueDefinition> inputs) { + this.inputs = inputs; + } + + @Override + public String toString() { + return "Operation [implementation=" + implementation + ", inputs=" + inputs + ", definition=" + definition + + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java new file mode 100644 index 0000000000..3b0708168b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +public class ParsedToscaYamlInfo { + Map<String, InputDefinition> inputs; + + Map<String, UploadComponentInstanceInfo> instances; + + Map<String, GroupDefinition> groups; + + public Map<String, UploadComponentInstanceInfo> getInstances() { + return instances; + } + + public void setInstances(Map<String, UploadComponentInstanceInfo> instances) { + this.instances = instances; + } + + public Map<String, GroupDefinition> getGroups() { + return groups; + } + + public void setGroups(Map<String, GroupDefinition> groups) { + this.groups = groups; + } + + public Map<String, InputDefinition> getInputs() { + return inputs; + } + + public void setInputs(Map<String, InputDefinition> inputs) { + this.inputs = inputs; + } + + @Override + public String toString() { + return "ParsedToscaYamlInfo [inputs=" + inputs + ", instances=" + instances + ", groups=" + groups + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java new file mode 100644 index 0000000000..e609f49321 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class Point { + + String x; + String y; + + public Point() { + super(); + } + + public Point(String x, String y) { + super(); + this.x = x; + this.y = y; + } + + public String getX() { + return x; + } + + public void setX(String x) { + this.x = x; + } + + public String getY() { + return y; + } + + public void setY(String y) { + this.y = y; + } + + @Override + public String toString() { + return "Point [x=" + x + ", y=" + y + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java new file mode 100644 index 0000000000..9b3e72ccc6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition; + +/** + * Specifies the policy type that the Node Type exposes. + */ +public class PolicyTypeDefinition extends PolicyTypeDataDefinition { + + private List<PropertyDefinition> properties; + + public List<PropertyDefinition> getProperties() { + return properties; + } + + public void setProperties(List<PropertyDefinition> properties) { + this.properties = properties; + } + + public PolicyTypeDefinition() { + super(); + } + + public PolicyTypeDefinition(PolicyTypeDataDefinition p) { + super(p); + } + + @Override + public String toString() { + return super.toString() + " [ properties=" + properties + " ]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java new file mode 100644 index 0000000000..04223857b7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class Product extends Component { + + public Product() { + super(new ProductMetadataDefinition()); + componentType = ComponentTypeEnum.PRODUCT; + } + + public Product(ProductMetadataDefinition productMetadataDefinition) { + super(productMetadataDefinition); + componentType = ComponentTypeEnum.PRODUCT; + } + + public String getFullName() { + return getProductMetadataDefinition().getFullName(); + } + + public void setFullName(String fullName) { + getProductMetadataDefinition().setFullName(fullName); + } + + public String getInvariantUUID() { + return getProductMetadataDefinition().getInvariantUUID(); + } + + public void setInvariantUUID(String invariantUUID) { + getProductMetadataDefinition().setInvariantUUID(invariantUUID); + } + + public List<String> getContacts() { + return getProductMetadataDefinition().getContacts(); + } + + public void setContacts(List<String> contacts) { + getProductMetadataDefinition().setContacts(contacts); + } + + public void addContact(String contact) { + getProductMetadataDefinition().addContact(contact); + } + + public Boolean getIsActive() { + return getProductMetadataDefinition().getIsActive(); + } + + public void setIsActive(Boolean isActive) { + getProductMetadataDefinition().setIsActive(isActive); + } + + private ProductMetadataDataDefinition getProductMetadataDefinition() { + return (ProductMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java new file mode 100644 index 0000000000..dc454d13b7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; + +public class ProductMetadataDefinition extends ComponentMetadataDefinition { + + public ProductMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ProductMetadataDataDefinition(); + } + + public ProductMetadataDefinition(ProductMetadataDataDefinition component) { + super(component); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java new file mode 100644 index 0000000000..b1e1552dfa --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java @@ -0,0 +1,34 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public interface PropertyConstraint { + + void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException; + + void validate(Object propertyValue) throws ConstraintViolationException; + + void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException; +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java new file mode 100644 index 0000000000..7974e863ac --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +//import javax.validation.Valid; +//import javax.validation.constraints.NotNull; +// +// +//import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +//import com.fasterxml.jackson.annotation.JsonProperty; +//import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class PropertyDefinition extends PropertyDataDefinition + implements IOperationParameter, IComplexDefaultValue, Serializable { + + /** + * + */ + private static final long serialVersionUID = 188403656600317269L; + + private List<PropertyConstraint> constraints; + // private Schema schema; + private String status; + + private String name; + + /** + * The resource id which this property belongs to + */ + private String parentUniqueId; + + public PropertyDefinition() { + super(); + } + + public PropertyDefinition(PropertyDataDefinition p) { + super(p); + } + + public PropertyDefinition(PropertyDefinition pd) { + this.setUniqueId(pd.getUniqueId()); + this.setConstraints(pd.getConstraints()); + // this.setSchema(pd.schema); + this.setDefaultValue(pd.getDefaultValue()); + this.setDescription(pd.getDescription()); + this.setName(pd.getName()); + this.setSchema(pd.getSchema()); + this.setParentUniqueId(pd.getParentUniqueId()); + this.setRequired(pd.isRequired()); + this.setType(pd.getType()); + } + + public List<PropertyConstraint> getConstraints() { + return constraints; + } + + public void setConstraints(List<PropertyConstraint> constraints) { + this.constraints = constraints; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return super.toString() + " [name=" + name + ", parentUniqueId=" + parentUniqueId + ", constraints=" + + constraints + "]]"; + } + + // public void setSchema(Schema entrySchema) { + // this.schema = entrySchema; + // + // } + // + // public Schema getSchema() { + // return schema; + // } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getParentUniqueId() { + return parentUniqueId; + } + + public void setParentUniqueId(String parentUniqueId) { + this.parentUniqueId = parentUniqueId; + } + + @Override + public boolean isDefinition() { + return false; + } + + public void setDefinition(boolean definition) { + this.definition = definition; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = super.hashCode(); + result = prime * result + ((constraints == null) ? 0 : constraints.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((parentUniqueId == null) ? 0 : parentUniqueId.hashCode()); + result = prime * result + ((status == null) ? 0 : status.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (!super.equals(obj)) + return false; + if (getClass() != obj.getClass()) + return false; + PropertyDefinition other = (PropertyDefinition) obj; + if (constraints == null) { + if (other.constraints != null) + return false; + } else if (!constraints.equals(other.constraints)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (parentUniqueId == null) { + if (other.parentUniqueId != null) + return false; + } else if (!parentUniqueId.equals(other.parentUniqueId)) + return false; + if (status == null) { + if (other.status != null) + return false; + } else if (!status.equals(other.status)) + return false; + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java new file mode 100644 index 0000000000..e46c433291 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class PropertyScope { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + PropertyScope other = (PropertyScope) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java new file mode 100644 index 0000000000..0c322420b3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.elements.InputsValueDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; + +public class PropertyValueDefinition extends InputsValueDataDefinition implements IOperationParameter { + + public PropertyValueDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public PropertyValueDefinition(String name, String value) { + super(name, value); + + } + + @Override + public boolean isDefinition() { + // TODO Auto-generated method stub + return false; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java new file mode 100644 index 0000000000..6028809454 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +public class RelationshipImpl implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8272341490256251337L; + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "RelationshipImpl [type=" + type + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java new file mode 100644 index 0000000000..84ead66658 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +public class RequirementAndRelationshipPair implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -5763126570618602135L; + + private String requirement; + private String capabilityOwnerId; + private String requirementOwnerId; + + private RelationshipImpl relationship; + + private String capability; + + private String capabilityUid; + private String requirementUid; + + public RequirementAndRelationshipPair() { + super(); + } + + public RequirementAndRelationshipPair(String requirement, RelationshipImpl relationship) { + super(); + this.requirement = requirement; + this.relationship = relationship; + } + + public RequirementAndRelationshipPair(String requirement, RelationshipImpl relationship, String capability) { + super(); + this.requirement = requirement; + this.relationship = relationship; + this.capability = capability; + } + + public String getRequirement() { + return requirement; + } + + public void setRequirement(String requirement) { + this.requirement = requirement; + } + + public String getCapabilityOwnerId() { + return capabilityOwnerId; + } + + public void setCapabilityOwnerId(String capabilityOwnerId) { + this.capabilityOwnerId = capabilityOwnerId; + } + + public String getRequirementOwnerId() { + return requirementOwnerId; + } + + public void setRequirementOwnerId(String requirementOwnerId) { + this.requirementOwnerId = requirementOwnerId; + } + + public RelationshipImpl getRelationship() { + return relationship; + } + + public void setRelationships(RelationshipImpl relationship) { + this.relationship = relationship; + } + + public String getCapability() { + return capability; + } + + public void setCapability(String capability) { + this.capability = capability; + } + + public String getCapabilityUid() { + return capabilityUid; + } + + public void setCapabilityUid(String capabilityUid) { + this.capabilityUid = capabilityUid; + } + + public String getRequirementUid() { + return requirementUid; + } + + public void setRequirementUid(String requirementUid) { + this.requirementUid = requirementUid; + } + + @Override + public String toString() { + return "RequirementAndRelationshipPair [requirement=" + requirement + ", relationship=" + relationship + + ", capability=" + capability + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java new file mode 100644 index 0000000000..345f2721ff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +public class RequirementCapabilityRelDef extends TargetCapabilityRelDef implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -6396265049494824741L; + + private String fromNode; + + public String getFromNode() { + return fromNode; + } + + public void setFromNode(String fromNode) { + this.fromNode = fromNode; + } + + @Override + public String toString() { + return "RequirementCapabilityRelDef [fromNode=" + fromNode + ", toString()=" + super.toString() + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java new file mode 100644 index 0000000000..3d5741255a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java @@ -0,0 +1,241 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; + +/** + * Specifies the requirements that the Node Type exposes. + */ +public class RequirementDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8840549489409274532L; + + /** + * Unique id of the requirement + */ + private String uniqueId; + + private String name; + + /** + * specify the capability type + */ + private String capability; + + /** + * specify the node type(Optional by tosca) + */ + private String node; + + /** + * specify the relationship type(Optional by tosca) + */ + private String relationship; + + // specifies the resource instance holding this requirement + private String ownerId; + private String ownerName; + + private String minOccurrences; + private String maxOccurrences; + + public RequirementDefinition() { + super(); + } + + public RequirementDefinition(RequirementDefinition other) { + this.uniqueId = other.uniqueId; + this.name = other.name; + this.capability = other.capability; + this.node = other.node; + this.relationship = other.relationship; + this.ownerId = other.ownerId; + this.ownerName = other.ownerName; + this.minOccurrences = other.minOccurrences; + this.maxOccurrences = other.maxOccurrences; + + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCapability() { + return capability; + } + + public void setCapability(String capability) { + this.capability = capability; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public String getRelationship() { + return relationship; + } + + public void setRelationship(String relationship) { + this.relationship = relationship; + } + + // public RequirementImplDef getRequirementImpl() { + // return requirementImpl; + // } + // + // public void setRequirementImpl(RequirementImplDef requirementImpl) { + // this.requirementImpl = requirementImpl; + // } + + public String getOwnerId() { + return ownerId; + } + + public void setOwnerId(String ownerId) { + this.ownerId = ownerId; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getMinOccurrences() { + return minOccurrences; + } + + public void setMinOccurrences(String minOccurrences) { + this.minOccurrences = minOccurrences; + } + + public String getMaxOccurrences() { + return maxOccurrences; + } + + public void setMaxOccurrences(String maxOccurrences) { + this.maxOccurrences = maxOccurrences; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((capability == null) ? 0 : capability.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((node == null) ? 0 : node.hashCode()); + result = prime * result + ((ownerId == null) ? 0 : ownerId.hashCode()); + result = prime * result + ((ownerName == null) ? 0 : ownerName.hashCode()); + result = prime * result + ((relationship == null) ? 0 : relationship.hashCode()); + result = prime * result + ((uniqueId == null) ? 0 : uniqueId.hashCode()); + result = prime * result + ((minOccurrences == null) ? 0 : minOccurrences.hashCode()); + result = prime * result + ((maxOccurrences == null) ? 0 : maxOccurrences.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + RequirementDefinition other = (RequirementDefinition) obj; + if (capability == null) { + if (other.capability != null) + return false; + } else if (!capability.equals(other.capability)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (node == null) { + if (other.node != null) + return false; + } else if (!node.equals(other.node)) + return false; + if (ownerId == null) { + if (other.ownerId != null) + return false; + } else if (!ownerId.equals(other.ownerId)) + return false; + if (ownerName == null) { + if (other.ownerName != null) + return false; + } else if (!ownerName.equals(other.ownerName)) + return false; + if (relationship == null) { + if (other.relationship != null) + return false; + } else if (!relationship.equals(other.relationship)) + return false; + if (uniqueId == null) { + if (other.uniqueId != null) + return false; + } else if (!uniqueId.equals(other.uniqueId)) + return false; + if (minOccurrences == null) { + if (other.minOccurrences != null) + return false; + } else if (!minOccurrences.equals(other.minOccurrences)) + return false; + if (maxOccurrences == null) { + if (other.maxOccurrences != null) + return false; + } else if (!maxOccurrences.equals(other.maxOccurrences)) + return false; + return true; + } + + @Override + public String toString() { + return "RequirementDefinition [uniqueId=" + uniqueId + ", name=" + name + ", capability=" + capability + + ", node=" + node + ", relationship=" + relationship + ", ownerId=" + ownerId + ", ownerName=" + + ownerName + ", minOccurrences=" + minOccurrences + ", maxOccurrences=" + maxOccurrences + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java new file mode 100644 index 0000000000..eb6bd01d4b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +public class RequirementImplDef { + + private String uniqueId; + + /** + * node type(mandatory). Unique id of the node we choose. + */ + private String nodeId; + + private Map<String, CapabiltyInstance> requirementProperties; + + private Point point; + + public String getNodeId() { + return nodeId; + } + + public void setNodeId(String nodeId) { + this.nodeId = nodeId; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public Map<String, CapabiltyInstance> getRequirementProperties() { + return requirementProperties; + } + + public void setRequirementProperties(Map<String, CapabiltyInstance> requirementProperties) { + this.requirementProperties = requirementProperties; + } + + public Point getPoint() { + return point; + } + + public void setPoint(Point point) { + this.point = point; + } + + @Override + public String toString() { + return "RequirementImplDef [uniqueId=" + uniqueId + ", nodeId=" + nodeId + ", requirementProperties=" + + requirementProperties + ", point=" + point + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java new file mode 100644 index 0000000000..14f4463216 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +/** + * Specifies the requirements that the Node Type exposes. + */ +public class RequirementInstance { + + /** + * specify the resource instance name as appears in the service + */ + private String node; + + /** + * specify the relationship impl + */ + private RelationshipImpl relationship; + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public RelationshipImpl getRelationship() { + return relationship; + } + + public void setRelationship(RelationshipImpl relationship) { + this.relationship = relationship; + } + + @Override + public String toString() { + return "RequirementInstance [node=" + node + ", relationship=" + relationship + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java new file mode 100644 index 0000000000..6490fb4ef1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java @@ -0,0 +1,273 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; + +public class Resource extends Component implements Serializable { + /** + * + */ + private static final long serialVersionUID = -6811540567661368482L; + + public Resource() { + super(new ResourceMetadataDefinition()); + componentType = ComponentTypeEnum.RESOURCE; + } + + public Resource(ComponentMetadataDefinition componentMetadataDefinition) { + super(componentMetadataDefinition); + componentType = ComponentTypeEnum.RESOURCE; + } + + private List<String> derivedFrom; + + private List<String> derivedList; + + private List<PropertyDefinition> properties; + + private List<AttributeDefinition> attributes; + + // Later + private Map<String, InterfaceDefinition> interfaces; + + private List<String> defaultCapabilities; + + private List<AdditionalInformationDefinition> additionalInformation; + + /** + * Please note that more than one "derivedFrom" resource is not currently + * supported by the app. The first list element is always addressed. + * + * @return + */ + public List<String> getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(List<String> derivedFrom) { + this.derivedFrom = derivedFrom; + } + + /** + * The derivedList is a chain of derivedFrom. e.g. if resource C is derived + * from resource B that is derived from resource A - then A, B is the + * "DerivedList" of resource C + * + * @return + */ + public List<String> getDerivedList() { + return derivedList; + } + + public void setDerivedList(List<String> derivedList) { + this.derivedList = derivedList; + } + + public List<PropertyDefinition> getProperties() { + return properties; + } + + public void setProperties(List<PropertyDefinition> properties) { + this.properties = properties; + } + + public List<AttributeDefinition> getAttributes() { + return attributes; + } + + public void setAttributes(List<AttributeDefinition> attributes) { + this.attributes = attributes; + } + + public Map<String, InterfaceDefinition> getInterfaces() { + return interfaces; + } + + public void setInterfaces(Map<String, InterfaceDefinition> interfaces) { + this.interfaces = interfaces; + } + + public Boolean isAbstract() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .isAbstract(); + } + + public void setAbstract(Boolean isAbstract) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setAbstract(isAbstract); + } + + public List<String> getDefaultCapabilities() { + return defaultCapabilities; + } + + public void setDefaultCapabilities(List<String> defaultCapabilities) { + this.defaultCapabilities = defaultCapabilities; + } + + public String getCost() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getCost(); + } + + public void setCost(String cost) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()).setCost(cost); + ; + } + + public String getLicenseType() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getLicenseType(); + } + + public void setLicenseType(String licenseType) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setLicenseType(licenseType); + } + + public List<AdditionalInformationDefinition> getAdditionalInformation() { + return additionalInformation; + } + + public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) { + this.additionalInformation = additionalInformation; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + super.hashCode(); + + result = prime * result + ((attributes == null) ? 0 : attributes.hashCode()); + // result = prime * result + ((capabilities == null) ? 0 : + // capabilities.hashCode()); + result = prime * result + ((defaultCapabilities == null) ? 0 : defaultCapabilities.hashCode()); + result = prime * result + ((derivedFrom == null) ? 0 : derivedFrom.hashCode()); + result = prime * result + ((interfaces == null) ? 0 : interfaces.hashCode()); + result = prime * result + ((properties == null) ? 0 : properties.hashCode()); + result = prime * result + ((derivedList == null) ? 0 : derivedList.hashCode()); + // result = prime * result + ((requirements == null) ? 0 : + // requirements.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + + Resource other = (Resource) obj; + if (attributes == null) { + if (other.attributes != null) + return false; + } else if (!attributes.equals(other.attributes)) + return false; + if (defaultCapabilities == null) { + if (other.defaultCapabilities != null) + return false; + } else if (!defaultCapabilities.equals(other.defaultCapabilities)) + return false; + if (derivedFrom == null) { + if (other.derivedFrom != null) + return false; + } else if (!derivedFrom.equals(other.derivedFrom)) + return false; + if (derivedList == null) { + if (other.derivedList != null) + return false; + } else if (!derivedList.equals(other.derivedList)) + return false; + if (interfaces == null) { + if (other.interfaces != null) + return false; + } else if (!interfaces.equals(other.interfaces)) + return false; + if (properties == null) { + if (other.properties != null) + return false; + } else if (!properties.equals(other.properties)) + return false; + + return super.equals(obj); + } + + @Override + public String toString() { + return "Resource [derivedFrom=" + derivedFrom + ", properties=" + properties + ", attributes=" + attributes + + ", interfaces=" + interfaces + // + ", capabilities=" + capabilities + ", requirements=" + + // requirements + + ", defaultCapabilities=" + defaultCapabilities + ", additionalInformation=" + additionalInformation + + "Metadata [" + getComponentMetadataDefinition().getMetadataDataDefinition().toString() + "]"; + } + + public String getToscaResourceName() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getToscaResourceName(); + } + + public void setToscaResourceName(String toscaResourceName) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setToscaResourceName(toscaResourceName); + } + + public ResourceTypeEnum getResourceType() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getResourceType(); + } + + public void setResourceType(ResourceTypeEnum resourceType) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setResourceType(resourceType); + } + + public void setVendorName(String vendorName) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setVendorName(vendorName); + } + + public void setVendorRelease(String vendorRelease) { + ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .setVendorRelease(vendorRelease); + } + + public String getVendorName() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getVendorName(); + } + + public String getVendorRelease() { + return ((ResourceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition()) + .getVendorRelease(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java new file mode 100644 index 0000000000..75dfdff444 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class ResourceInstanceHeatParameter extends HeatParameterDefinition { + + private String valueUniqueId; + + public ResourceInstanceHeatParameter() { + super(); + } + + public ResourceInstanceHeatParameter(HeatParameterDefinition heatParameterDefinition, String valueId) { + super(heatParameterDefinition); + valueUniqueId = valueId; + } + + public String getValueUniqueId() { + return valueUniqueId; + } + + public void setValueUniqueId(String valueUniqueId) { + this.valueUniqueId = valueUniqueId; + } + + @Override + public String toString() { + return "ResourceInstanceHeatParameter [ " + super.toString() + " , valueUniqueId = " + valueUniqueId + " ]"; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java new file mode 100644 index 0000000000..2448191fc9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; + +public class ResourceMetadataDefinition extends ComponentMetadataDefinition { + + public ResourceMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ResourceMetadataDataDefinition(); + } + + public ResourceMetadataDefinition(ResourceMetadataDataDefinition other) { + super(other); + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java new file mode 100644 index 0000000000..cce4820870 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +/** + * Schema allows to create new types that can be used along TOSCA definitions. + */ +public class Schema { + private String derivedFrom; + private List<PropertyConstraint> constraints; + private Map<String, PropertyDefinition> properties; + private PropertyDefinition property; + + public PropertyDefinition getProperty() { + return property; + } + + public void setProperty(PropertyDefinition property) { + this.property = property; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java new file mode 100644 index 0000000000..e47333457f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java @@ -0,0 +1,100 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; + +public class Service extends Component { + public Service() { + super(new ServiceMetadataDefinition()); + componentType = ComponentTypeEnum.SERVICE; + } + + public Service(ComponentMetadataDefinition serviceMetadataDefinition) { + super(serviceMetadataDefinition); + componentType = ComponentTypeEnum.SERVICE; + } + + private Map<String, ArtifactDefinition> serviceApiArtifacts; + + private List<AdditionalInformationDefinition> additionalInformation; + + public Map<String, ArtifactDefinition> getServiceApiArtifacts() { + return serviceApiArtifacts; + } + + public void setServiceApiArtifacts(Map<String, ArtifactDefinition> serviceApiArtifacts) { + this.serviceApiArtifacts = serviceApiArtifacts; + } + + public String getProjectCode() { + return getServiceMetadataDefinition().getProjectCode(); + } + + public void setProjectCode(String projectName) { + getServiceMetadataDefinition().setProjectCode(projectName); + } + + public DistributionStatusEnum getDistributionStatus() { + String distributionStatus = getServiceMetadataDefinition().getDistributionStatus(); + if (distributionStatus != null) { + return DistributionStatusEnum.valueOf(distributionStatus); + } else { + return null; + } + } + + public void setDistributionStatus(DistributionStatusEnum distributionStatus) { + if (distributionStatus != null) + getServiceMetadataDefinition().setDistributionStatus(distributionStatus.name()); + } + + private ServiceMetadataDataDefinition getServiceMetadataDefinition() { + return (ServiceMetadataDataDefinition) getComponentMetadataDefinition().getMetadataDataDefinition(); + } + + public List<AdditionalInformationDefinition> getAdditionalInformation() { + return additionalInformation; + } + + public void setAdditionalInformation(List<AdditionalInformationDefinition> additionalInformation) { + this.additionalInformation = additionalInformation; + } + + @Override + public String toString() { + return "Service [componentMetadataDefinition=" + getComponentMetadataDefinition() + // + ", resourceInstances=" + resourceInstances + ", + // resourceInstancesRelations=" + resourceInstancesRelations + ", + // resourceInstancesRelations=" + // + resourceInstancesRelations + + " ]"; + } + + @Override + public void setSpecificComponetTypeArtifacts(Map<String, ArtifactDefinition> specificComponentTypeArtifacts) { + setServiceApiArtifacts(specificComponentTypeArtifacts); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java new file mode 100644 index 0000000000..21b2e43873 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; + +public class ServiceMetadataDefinition extends ComponentMetadataDefinition { + + public ServiceMetadataDefinition() { + super(); + this.componentMetadataDataDefinition = new ServiceMetadataDataDefinition(); + } + + public ServiceMetadataDefinition(ServiceMetadataDataDefinition component) { + super(component); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java new file mode 100644 index 0000000000..f3edfe2c6c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public class Tag { + + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + Tag other = (Tag) obj; + if (name == null) { + if (other.getClass() != null) { + return false; + } + } else if (!name.equals(other.getName())) { + return false; + } + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java new file mode 100644 index 0000000000..2e92ca5df3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.io.Serializable; +import java.util.List; + +public class TargetCapabilityRelDef implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -7571489368200736413L; + + private String toNode; + + // private List<ImmutablePair<String, RelationshipImpl>> relationships; + + private List<RequirementAndRelationshipPair> relationships; + + public TargetCapabilityRelDef() { + super(); + } + + public TargetCapabilityRelDef(String toNode, List<RequirementAndRelationshipPair> relationships) { + super(); + this.toNode = toNode; + this.relationships = relationships; + } + + public String getToNode() { + return toNode; + } + + public void setToNode(String toNode) { + this.toNode = toNode; + } + + // public String getCapabilityOwnerId() { + // return capabilityOwnerId; + // } + // + // public void setCapabilityOwnerId(String capabilityOwnerId) { + // this.capabilityOwnerId = capabilityOwnerId; + // } + + public List<RequirementAndRelationshipPair> getRelationships() { + return relationships; + } + + public void setRelationships(List<RequirementAndRelationshipPair> relationships) { + this.relationships = relationships; + } + + @Override + public String toString() { + return "TargetCapabilityRelDef [ toNode=" + toNode + // + ", capabilityOwnerId=" + capabilityOwnerId + + ", relationships=" + relationships + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java new file mode 100644 index 0000000000..d16330481e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; + +public class UploadCapInfo extends UploadInfo { + /** + * specify the node type(Optional by tosca) + */ + private List<String> validSourceTypes; + + private List<UploadPropInfo> properties; + + private String node; + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public List<String> getValidSourceTypes() { + return validSourceTypes; + } + + public void setValidSourceTypes(List<String> validSourceTypes) { + this.validSourceTypes = validSourceTypes; + } + + public List<UploadPropInfo> getProperties() { + return properties; + } + + public void setProperties(List<UploadPropInfo> properties) { + this.properties = properties; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java new file mode 100644 index 0000000000..329e816ea7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +public class UploadComponentInstanceInfo { + private String name; + private String type; + private Map<String, List<UploadCapInfo>> capabilities; + private Map<String, List<UploadReqInfo>> requirements; + private Map<String, List<UploadPropInfo>> properties; + + public Map<String, List<UploadPropInfo>> getProperties() { + return properties; + } + + public void setProperties(Map<String, List<UploadPropInfo>> properties) { + this.properties = properties; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Map<String, List<UploadCapInfo>> getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map<String, List<UploadCapInfo>> capabilities) { + this.capabilities = capabilities; + } + + public Map<String, List<UploadReqInfo>> getRequirements() { + return requirements; + } + + public void setRequirements(Map<String, List<UploadReqInfo>> requirements) { + this.requirements = requirements; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java new file mode 100644 index 0000000000..75707ee77c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +public abstract class UploadInfo { + + private String type; + + private String name; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java new file mode 100644 index 0000000000..60a58c9aed --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.List; +import java.util.Map; + +public class UploadPropInfo extends UploadInfo { + + private Object value; + + private String description; + + private boolean password; + + private List<GetInputValueInfo> get_input; + + public List<GetInputValueInfo> getGet_input() { + return get_input; + } + + public void setGet_input(List<GetInputValueInfo> get_input) { + this.get_input = get_input; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public boolean isPassword() { + return password; + } + + public void setPassword(boolean password) { + this.password = password; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java new file mode 100644 index 0000000000..7f2834bddf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.Map; + +public class UploadReqInfo extends UploadInfo { + /** + * specify the node type(Optional by tosca) + */ + + private String capabilityName; + + private String node; + + public String getCapabilityName() { + return capabilityName; + } + + public void setCapabilityName(String capabilityName) { + this.capabilityName = capabilityName; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java new file mode 100644 index 0000000000..385b15c728 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java @@ -0,0 +1,304 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.common.api.UploadArtifactInfo; + +public class UploadResourceInfo { + + public UploadResourceInfo(String payload, String payloadName, String description, String category, + List<String> tags, List<UploadArtifactInfo> artifactsList) { + super(); + this.payloadData = payload; + this.payloadName = payloadName; + this.description = description; + // this.category = category; + this.tags = tags; + this.artifactList = artifactsList; + if (category != null) { + String[] arr = category.split("/"); + if (arr.length >= 2) { + categories = new ArrayList<>(); + CategoryDefinition catDef = new CategoryDefinition(); + catDef.setName(arr[0]); + SubCategoryDefinition subCat = new SubCategoryDefinition(); + subCat.setName(arr[1]); + catDef.addSubCategory(subCat); + categories.add(catDef); + } + } + } + + public UploadResourceInfo() { + } + + private String payloadData; + private String payloadName; + private String description; + // private String category; + private List<String> tags; + private List<CategoryDefinition> categories; + + private List<UploadArtifactInfo> artifactList; + private String contactId, name, resourceIconPath, icon, vendorName, vendorRelease; + + private String resourceType = "VFC"; + + public String getPayloadData() { + return payloadData; + } + + public void setPayloadData(String payload) { + this.payloadData = payload; + } + + public String getPayloadName() { + return payloadName; + } + + public void setPayloadName(String payloadName) { + this.payloadName = payloadName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + // public String getCategory() { + // return category; + // } + // public void setCategory(String category) { + // this.category = category; + // } + public List<String> getTags() { + return tags; + } + + public void setTags(List<String> tags) { + this.tags = tags; + } + + public List<UploadArtifactInfo> getArtifactList() { + return artifactList; + } + + public void setArtifactList(List<UploadArtifactInfo> artifactsList) { + this.artifactList = artifactsList; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((artifactList == null) ? 0 : artifactList.hashCode()); + result = prime * result + ((contactId == null) ? 0 : contactId.hashCode()); + // result = prime * result + ((category == null) ? 0 : + // category.hashCode()); + result = prime * result + ((description == null) ? 0 : description.hashCode()); + result = prime * result + ((icon == null) ? 0 : icon.hashCode()); + result = prime * result + ((payloadData == null) ? 0 : payloadData.hashCode()); + result = prime * result + ((payloadName == null) ? 0 : payloadName.hashCode()); + result = prime * result + ((resourceIconPath == null) ? 0 : resourceIconPath.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((tags == null) ? 0 : tags.hashCode()); + result = prime * result + ((vendorName == null) ? 0 : vendorName.hashCode()); + result = prime * result + ((vendorRelease == null) ? 0 : vendorRelease.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + UploadResourceInfo other = (UploadResourceInfo) obj; + if (artifactList == null) { + if (other.artifactList != null) + return false; + } else if (!artifactList.equals(other.artifactList)) + return false; + if (contactId == null) { + if (other.contactId != null) + return false; + } else if (!contactId.equals(other.contactId)) + return false; + // if (category == null) { + // if (other.category != null) + // return false; + // } else if (!category.equals(other.category)) + // return false; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + if (icon == null) { + if (other.icon != null) + return false; + } else if (!icon.equals(other.icon)) + return false; + if (payloadData == null) { + if (other.payloadData != null) + return false; + } else if (!payloadData.equals(other.payloadData)) + return false; + if (payloadName == null) { + if (other.payloadName != null) + return false; + } else if (!payloadName.equals(other.payloadName)) + return false; + if (resourceIconPath == null) { + if (other.resourceIconPath != null) + return false; + } else if (!resourceIconPath.equals(other.resourceIconPath)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (tags == null) { + if (other.tags != null) + return false; + } else if (!tags.equals(other.tags)) + return false; + if (vendorName == null) { + if (other.vendorName != null) + return false; + } else if (!vendorName.equals(other.vendorName)) + return false; + if (vendorRelease == null) { + if (other.vendorRelease != null) + return false; + } else if (!vendorRelease.equals(other.vendorRelease)) + return false; + return true; + } + + public String getContactId() { + return contactId; + } + + public void setContactId(String userId) { + this.contactId = userId; + } + + public String getName() { + return name; + } + + public void setName(String resourceName) { + this.name = resourceName; + } + + // Icon when using UI import otherwise resourceIconPath + public String getResourceIconPath() { + return (resourceIconPath != null) ? resourceIconPath : icon; + } + + public void setResourceIconPath(String resourceIconPath) { + this.resourceIconPath = resourceIconPath; + } + + public String getVendorName() { + return vendorName; + } + + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + } + + public String getVendorRelease() { + return vendorRelease; + } + + public void setVendorRelease(String vendorRelease) { + this.vendorRelease = vendorRelease; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public List<CategoryDefinition> getCategories() { + return categories; + } + + public void setCategories(List<CategoryDefinition> categories) { + this.categories = categories; + } + + public void addSubCategory(String category, String subCategory) { + if (category != null || subCategory != null) { + if (categories == null) { + categories = new ArrayList<>(); + } + CategoryDefinition selectedCategory = null; + for (CategoryDefinition categoryDef : categories) { + if (categoryDef.getName().equals(category)) { + selectedCategory = categoryDef; + } + } + if (selectedCategory == null) { + selectedCategory = new CategoryDefinition(); + selectedCategory.setName(category); + categories.add(selectedCategory); + } + List<SubCategoryDefinition> subcategories = selectedCategory.getSubcategories(); + if (subcategories == null) { + subcategories = new ArrayList<>(); + selectedCategory.setSubcategories(subcategories); + } + SubCategoryDefinition selectedSubcategory = null; + for (SubCategoryDefinition subcategory : subcategories) { + if (subcategory.getName().equals(subCategory)) { + selectedSubcategory = subcategory; + } + } + if (selectedSubcategory == null) { + selectedSubcategory = new SubCategoryDefinition(); + selectedSubcategory.setName(subCategory); + subcategories.add(selectedSubcategory); + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java new file mode 100644 index 0000000000..129c35b708 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java @@ -0,0 +1,205 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model; + +import org.joda.time.DateTime; +import org.joda.time.DateTimeZone; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.resources.data.UserData; + +public class User { + public static final String FORCE_DELETE_HEADER_FLAG = "FORCE_DELETE"; + + private String firstName; + + private String lastName; + + private String userId; + + private String email; + + private String role; + + private Long lastLoginTime; + + private UserStatusEnum status = UserStatusEnum.ACTIVE; + + public User() { + } + + public User(UserData userDate) { + this(userDate.getFirstName(), userDate.getLastName(), userDate.getUserId(), userDate.getEmail(), + userDate.getRole(), userDate.getLastLoginTime()); + } + + public User(String firstName, String lastName, String userId, String emailAddress, String role, + Long lastLoginTime) { + this.firstName = firstName; + this.lastName = lastName; + this.userId = userId; + this.email = emailAddress; + this.role = role; + this.lastLoginTime = lastLoginTime; + + } + + public void copyData(User other) { + this.firstName = other.getFirstName(); + this.lastName = other.getLastName(); + this.userId = other.getUserId(); + this.email = other.getEmail(); + this.role = other.getRole(); + this.lastLoginTime = other.getLastLoginTime(); + + } + + public User(User aUser) { + this(aUser.getFirstName(), aUser.getLastName(), aUser.getUserId(), aUser.getEmail(), aUser.getRole(), + aUser.getLastLoginTime()); + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getFullName() { + return this.getFirstName() + " " + this.getLastName(); + } + + public void setLastLoginTime() { + DateTime now = new DateTime(DateTimeZone.UTC); + this.lastLoginTime = now.getMillis(); + } + + public void setLastLoginTime(Long time) { + this.lastLoginTime = time; + } + + public Long getLastLoginTime() { + return this.lastLoginTime; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((userId == null) ? 0 : userId.hashCode()); + result = prime * result + ((email == null) ? 0 : email.hashCode()); + result = prime * result + ((firstName == null) ? 0 : firstName.hashCode()); + result = prime * result + ((lastName == null) ? 0 : lastName.hashCode()); + result = prime * result + ((role == null) ? 0 : role.hashCode()); + result = prime * result + ((lastLoginTime == null) ? 0 : lastLoginTime.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + User other = (User) obj; + if (userId == null) { + if (other.userId != null) + return false; + } else if (!userId.equals(other.userId)) + return false; + if (email == null) { + if (other.email != null) + return false; + } else if (!email.equals(other.email)) + return false; + if (firstName == null) { + if (other.firstName != null) + return false; + } else if (!firstName.equals(other.firstName)) + return false; + if (lastName == null) { + if (other.lastName != null) + return false; + } else if (!lastName.equals(other.lastName)) + return false; + if (role == null) { + if (other.role != null) + return false; + } else if (!role.equals(other.role)) + return false; + if (lastLoginTime == null) { + if (other.lastLoginTime != null) + return false; + } else if (!lastLoginTime.equals(other.lastLoginTime)) + return false; + return true; + } + + public UserStatusEnum getStatus() { + return status; + } + + public void setStatus(UserStatusEnum status) { + this.status = status; + } + + @Override + public String toString() { + return "User [firstName=" + firstName + ", lastName=" + lastName + ", userId=" + userId + ", email=" + email + + ", role=" + role + ", last login time=" + lastLoginTime + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java new file mode 100644 index 0000000000..bb8a1b0129 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; + +import fj.data.Either; + +public interface ApplicationCache<T> { + + public abstract Either<Map<String, T>, TitanOperationStatus> getAll(); + + public abstract Either<T, TitanOperationStatus> get(String uniqueId); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java new file mode 100644 index 0000000000..31664c929b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java @@ -0,0 +1,335 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheConfig; +import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheInfo; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.resources.data.DataTypeData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("application-datatype-cache") +public class ApplicationDataTypeCache implements ApplicationCache<DataTypeDefinition>, Runnable { + + private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(); + private final Lock r = rwl.readLock(); + private final Lock w = rwl.writeLock(); + + private Map<String, DataTypeDefinition> data = new HashMap<>(); + + private ScheduledExecutorService scheduledPollingService = Executors.newScheduledThreadPool(1, + new BasicThreadFactory.Builder().namingPattern("ApplicationDataTypeCacheThread-%d").build()); + ScheduledFuture<?> scheduledFuture = null; + + private static Logger log = LoggerFactory.getLogger(ApplicationDataTypeCache.class.getName()); + + private int firstRunDelayInSec = 30; + private int pollingIntervalInSec = 60; + + @Resource + private PropertyOperation propertyOperation; + + @PostConstruct + public void init() { + + ApplicationL1CacheConfig applicationL1CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL1Cache(); + if (applicationL1CacheConfig != null) { + if (applicationL1CacheConfig.getDatatypes() != null) { + ApplicationL1CacheInfo datatypesInfo = applicationL1CacheConfig.getDatatypes(); + if (datatypesInfo.getEnabled()) { + Integer intervalInSec = datatypesInfo.getPollIntervalInSec(); + if (intervalInSec != null) { + pollingIntervalInSec = intervalInSec; + } + Integer firstRunDelay = datatypesInfo.getFirstRunDelay(); + if (firstRunDelay != null) { + firstRunDelayInSec = firstRunDelay; + } + log.trace("ApplicationDataTypesCache polling interval is " + pollingIntervalInSec + " seconds."); + if (scheduledPollingService != null) { + log.debug("Start ApplicationDataTypeCache polling task. polling interval {} seconds", + pollingIntervalInSec); + scheduledFuture = scheduledPollingService.scheduleAtFixedRate(this, firstRunDelayInSec, + pollingIntervalInSec, TimeUnit.SECONDS); + } + + } + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled", + ErrorSeverity.INFO); + } + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("ApplicationDataTypesCache", "Cache is disabled", + ErrorSeverity.INFO); + } + + } + + @PreDestroy + void destroy() { + + if (scheduledFuture != null) { + boolean result = scheduledFuture.cancel(true); + log.debug("Stop polling task. result = {}", result); + + scheduledFuture = null; + } + shutdownExecutor(); + } + + private void shutdownExecutor() { + if (scheduledPollingService == null) + return; + + scheduledPollingService.shutdown(); // Disable new tasks from being + // submitted + try { + // Wait a while for existing tasks to terminate + if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) { + scheduledPollingService.shutdownNow(); // Cancel currently + // executing tasks + // Wait a while for tasks to respond to being cancelled + if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) + log.debug("Pool did not terminate"); + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + scheduledPollingService.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + + private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypesFromGraph() { + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = propertyOperation + .getAllDataTypes(); + + return allDataTypes; + + } + + @Override + public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAll() { + + try { + + r.lock(); + if (data == null || data.isEmpty()) { + return getAllDataTypesFromGraph(); + } + + return Either.left(data); + + } finally { + r.unlock(); + } + } + + @Override + public Either<DataTypeDefinition, TitanOperationStatus> get(String uniqueId) { + + try { + r.lock(); + + if (data == null || data.isEmpty()) { + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = propertyOperation + .getDataTypeByUid(uniqueId); + return dataTypeByUid; + } else { + DataTypeDefinition dataTypeDefinition = data.values().stream() + .filter(p -> p.getUniqueId().equals(uniqueId)).findFirst().orElse(null); + if (dataTypeDefinition == null) { + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = propertyOperation + .getDataTypeByUid(uniqueId); + return dataTypeByUid; + } else { + return Either.left(dataTypeDefinition); + } + } + } finally { + r.unlock(); + } + } + + @Override + public void run() { + log.trace("run() method. polling db to fetch data types"); + + try { + + Long start = System.currentTimeMillis(); + log.trace("Start fetching all data types from db"); + Either<List<DataTypeData>, TitanOperationStatus> allDataTypeNodes = propertyOperation.getAllDataTypeNodes(); + Long end = System.currentTimeMillis(); + log.trace("Finish fetching all data types from db. Took " + (end - start) + " Milliseconds"); + if (allDataTypeNodes.isRight()) { + TitanOperationStatus status = allDataTypeNodes.right().value(); + if (status != TitanOperationStatus.OK) { + log.debug("ApplicationDataTypesCache - Failed to fetch all data types nodes"); + BeEcompErrorManager.getInstance().logInternalConnectionError("FetchDataTypes", + "Failed to fetch data types from graph(cache)", ErrorSeverity.INFO); + } + } else { + + List<DataTypeData> list = allDataTypeNodes.left().value(); + if (list != null) { + + Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime = list.stream() + .collect(Collectors.toMap(p -> p.getDataTypeDataDefinition().getName(), + p -> new ImmutablePair<Long, Long>(p.getDataTypeDataDefinition().getCreationTime(), + p.getDataTypeDataDefinition().getModificationTime()))); + + Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime = new HashMap<>(); + try { + r.lock(); + if (data != null) { + currentDataTypeToModificationTime = data.values().stream().collect(Collectors.toMap( + p -> p.getName(), + p -> new ImmutablePair<Long, Long>(p.getCreationTime(), p.getModificationTime()))); + + } + } finally { + r.unlock(); + } + + boolean isChanged = compareDataTypes(dataTypeNameToModificationTime, + currentDataTypeToModificationTime); + if (isChanged) { + replaceAllData(); + } + + } + } + + } catch (Exception e) { + log.debug("unexpected error occured", e); + + BeEcompErrorManager.getInstance().logInternalUnexpectedError("ApplicationDataTypesCache", + "Failed to run refresh data types job", ErrorSeverity.INFO); + } finally { + try { + propertyOperation.getTitanGenericDao().commit(); + } catch (Exception e) { + log.trace("Failed to commit ApplicationDataTypeCache", e); + } + } + + } + + private boolean compareDataTypes(Map<String, ImmutablePair<Long, Long>> dataTypeNameToModificationTime, + Map<String, ImmutablePair<Long, Long>> currentDataTypeToModificationTime) { + if (dataTypeNameToModificationTime.size() != currentDataTypeToModificationTime.size()) { + return true; + } else { + + Set<String> currentkeySet = currentDataTypeToModificationTime.keySet(); + Set<String> keySet = dataTypeNameToModificationTime.keySet(); + + if (currentkeySet.containsAll(keySet)) { + + for (Entry<String, ImmutablePair<Long, Long>> entry : dataTypeNameToModificationTime.entrySet()) { + String dataTypeName = entry.getKey(); + ImmutablePair<Long, Long> creationAndModificationTimes = entry.getValue(); + long creationTime = creationAndModificationTimes.getLeft() == null ? 0 + : creationAndModificationTimes.getLeft().longValue(); + long modificationTime = creationAndModificationTimes.getRight() == null ? 0 + : creationAndModificationTimes.getRight().longValue(); + + ImmutablePair<Long, Long> currentEntry = currentDataTypeToModificationTime.get(dataTypeName); + long currentCreationTime = currentEntry.getLeft() == null ? 0 : currentEntry.getLeft().longValue(); + long currentModificationTime = currentEntry.getRight() == null ? 0 + : currentEntry.getRight().longValue(); + + if (creationTime > currentCreationTime || modificationTime > currentModificationTime) { + log.debug("Datatype {} was updated. Creation Time {} vs {}. Modification Time {} vs {}", + dataTypeName, currentCreationTime, creationTime, currentModificationTime, + modificationTime); + return true; + } + } + } else { + return true; + } + + } + + return false; + } + + private void replaceAllData() { + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = propertyOperation + .getAllDataTypes(); + + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Failed to fetch all data types from db. Status is {}", status); + } else { + + try { + w.lock(); + + Map<String, DataTypeDefinition> newDataTypes = allDataTypes.left().value(); + data = newDataTypes; + + BeEcompErrorManager.getInstance().logInternalFlowError("ReplaceDataTypesCache", + "Succeed to replace the data types cache", ErrorSeverity.INFO); + + } finally { + w.unlock(); + } + + } + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java new file mode 100644 index 0000000000..6732adbdb1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java @@ -0,0 +1,997 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantReadWriteLock; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.config.Configuration.ApplicationL1CacheCatalogInfo; +import org.openecomp.sdc.be.config.Configuration.ApplicationL2CacheConfig; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.cassandra.ComponentCassandraDao; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.*; +import org.openecomp.sdc.be.resources.data.ComponentCacheData; +import org.openecomp.sdc.common.util.SerializationUtils; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("component-cache") +public class ComponentCache { + + private static Logger logger = LoggerFactory.getLogger(ComponentCache.class.getName()); + + @javax.annotation.Resource + ComponentCassandraDao componentCassandraDao; + + @javax.annotation.Resource + ResourceOperation resourceOperation; + + @javax.annotation.Resource + ServiceOperation serviceOperation; + + @javax.annotation.Resource + ProductOperation productOperation; + + private Map<ComponentTypeEnum, Map<String, Component>> catalogInMemoryCache = new HashMap<>(); + private final ReentrantReadWriteLock rwCatalogLock = new ReentrantReadWriteLock(); + private final Lock rCatalogLock = rwCatalogLock.readLock(); + private final Lock wCatalogLock = rwCatalogLock.writeLock(); + + boolean enabled = true; + int catalogInMemorySizePerResource = 300; + int catalogInMemorySizePerService = 200; + int catalogInMemorySizePerProduct = 100; + boolean catalogInMemoryEnabled = true; + Map<ComponentTypeEnum, Integer> limitMemoryCatalogSizePerType = new HashMap<>(); + + @PostConstruct + public void init() { + + Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); + if (configuration != null) { + ApplicationL2CacheConfig applicationL2Cache = configuration.getApplicationL2Cache(); + if (applicationL2Cache != null) { + boolean isEnabled = applicationL2Cache.isEnabled(); + this.enabled = isEnabled; + + ApplicationL1CacheCatalogInfo catalog = applicationL2Cache.getCatalogL1Cache(); + if (catalog != null) { + catalogInMemoryEnabled = catalog.getEnabled(); + catalogInMemorySizePerResource = catalog.getResourcesSizeInCache(); + catalogInMemorySizePerService = catalog.getServicesSizeInCache(); + catalogInMemorySizePerProduct = catalog.getProductsSizeInCache(); + } + } + } + + ComponentTypeEnum[] typesForCache = { ComponentTypeEnum.RESOURCE, ComponentTypeEnum.SERVICE, + ComponentTypeEnum.PRODUCT }; + for (ComponentTypeEnum typeEnum : typesForCache) { + Map<String, Component> map = new HashMap<>(); + catalogInMemoryCache.put(typeEnum, map); + } + + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.RESOURCE, catalogInMemorySizePerResource); + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.SERVICE, catalogInMemorySizePerService); + limitMemoryCatalogSizePerType.put(ComponentTypeEnum.PRODUCT, catalogInMemorySizePerProduct); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + this.enabled = enabled; + } + + public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime, + Function<Component, Component> filterFieldsFunc) { + + Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache( + componentUid, lastModificationTime, filterFieldsFunc); + + if (componentFromCache.isRight()) { + return Either.right(componentFromCache.right().value()); + } + + return Either.left(componentFromCache.left().value().left); + + } + + public Either<List<ComponentCacheData>, ActionStatus> getAllComponentIdTimeAndType() { + if (false == isEnabled()) { + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either<List<ComponentCacheData>, ActionStatus> componentRes = componentCassandraDao + .getAllComponentIdTimeAndType(); + + return componentRes; + + } + + /** + * get components for catalog + * + * @param components + * @param componentTypeEnum + * @return + */ + @Deprecated + public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog( + Set<String> components, ComponentTypeEnum componentTypeEnum) { + + if (false == isEnabled()) { + logger.debug("In getComponentsForCatalog for type {}. Cache is disabled.", + componentTypeEnum.name().toLowerCase()); + return Either.right(ActionStatus.NOT_ALLOWED); + } + logger.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase()); + + Function<List<Component>, List<Component>> filterFieldsFunc = x -> filterForCatalog(x); + + Set<String> leftComponentsForSearch = new HashSet<>(); + leftComponentsForSearch.addAll(components); + + // get components from inmemory cache + List<Component> componentsFromMemory = null; + if (true == catalogInMemoryEnabled) { + componentsFromMemory = getDataFromInMemoryCache(components, componentTypeEnum); + logger.debug("The number of components of type {} fetched from memory is {}", + componentTypeEnum.name().toLowerCase(), + componentsFromMemory == null ? 0 : componentsFromMemory.size()); + if (componentsFromMemory != null) { + componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId())); + } + } else { + logger.debug("Catalog InMemory cache is disabled"); + } + + logger.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(), + leftComponentsForSearch.size()); + + // get components from cassandra cache and filter each component + Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> result = getComponents( + leftComponentsForSearch, filterFieldsFunc); + + if (result.isLeft()) { + // add inmemory components to the valid components(not dirty) + List<Component> foundComponents = result.left().value().getLeft(); + if (componentsFromMemory != null) { + foundComponents.addAll(componentsFromMemory); + } + if (true == catalogInMemoryEnabled) { + updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum); + } + } + + return result; + } + + /** + * @param foundComponents + * @param componentTypeEnum + */ + private void updateCatalogInMemoryCacheWithCertified(List<Component> foundComponents, + ComponentTypeEnum componentTypeEnum) { + + try { + wCatalogLock.lock(); + + long start = System.currentTimeMillis(); + Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum); + int mapSizeBefore = map.size(); + map.clear(); + Map<String, Component> collect = foundComponents.stream() + .filter(p -> p.getLifecycleState() == LifecycleStateEnum.CERTIFIED) + .limit(limitMemoryCatalogSizePerType.get(componentTypeEnum)) + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p)); + map.putAll(collect); + logger.debug( + "Size of in memory cache for catalog {}(certified only): Before {}, After {}. Replacement Time is {} ms.", + componentTypeEnum.name().toLowerCase(), mapSizeBefore, map.size(), + System.currentTimeMillis() - start); + } finally { + wCatalogLock.unlock(); + } + + } + + private List<Component> getDataFromInMemoryCache(Set<String> components, ComponentTypeEnum componentTypeEnum) { + List<Component> foundComponents = new ArrayList<>(); + + try { + + rCatalogLock.lock(); + + Map<String, Component> map = catalogInMemoryCache.get(componentTypeEnum); + for (String compUid : components) { + Component component = map.get(compUid); + if (component != null) { + foundComponents.add(component); + } + } + + } finally { + rCatalogLock.unlock(); + } + + return foundComponents; + } + + /** + * + * get full components from cassandra. On each component apply filter + * function in order to remove unused members + * + * @param components + * @param filterFieldsFunc + * @return <found components, found dirty components, not found components + * list> or Error + */ + public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponents( + Set<String> components, Function<List<Component>, List<Component>> filterFieldsFunc) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull( + components); + + if (componentsFull.isRight()) { + return Either.right(componentsFull.right().value()); + } + + ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsFull.left().value(); + List<Component> foundResources = immutableTriple.left; + List<Component> foundDirtyResources = immutableTriple.middle; + Set<String> notFoundResources = immutableTriple.right; + + List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources); + List<Component> filterdFoundDirtyResources = filterFieldsFunc.apply(foundDirtyResources); + + ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<List<Component>, List<Component>, Set<String>>( + filterdFoundResources, filterdFoundDirtyResources, notFoundResources); + + return Either.left(result); + + } + + public Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsForLeftPanel( + ComponentTypeEnum componentTypeEnum, String internalComponentType, Set<String> filteredResources) { + + logger.debug("In getComponentsForLeftPanel componentTypeEnum = {}, internalComponentType = {}", + componentTypeEnum, internalComponentType); + + Function<List<Component>, List<Component>> filterFieldsFunc = x -> filterForLeftPanel(x); + + return getComponents(filteredResources, filterFieldsFunc); + + } + + private List<Component> filterForLeftPanel(List<Component> components) { + + List<Component> result = new ArrayList<>(); + if (components != null) { + components.forEach(p -> result.add(filterFieldsForLeftPanel(p))); + } + + return result; + } + + private List<Component> filterForCatalog(List<Component> components) { + + List<Component> result = new ArrayList<>(); + if (components != null) { + components.forEach(p -> result.add(filterFieldsForCatalog(p))); + } + + return result; + } + + private Component filterFieldsForLeftPanel(Component component) { + + Component result = null; + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + switch (componentTypeEnum) { + case RESOURCE: + result = new Resource(); + copyFieldsForLeftPanel(component, result); + break; + case SERVICE: + result = new Service(); + copyFieldsForLeftPanel(component, result); + break; + default: + break; + } + + return result; + } + + private Component filterFieldsForCatalog(Component component) { + + Component result = null; + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + switch (componentTypeEnum) { + case RESOURCE: + result = new Resource(); + copyFieldsForCatalog(component, result); + break; + case SERVICE: + result = new Service(); + copyFieldsForCatalog(component, result); + break; + case PRODUCT: + result = new Product(); + copyFieldsForCatalog(component, result); + default: + break; + } + + return result; + } + + /** + * Copy relevant fields to the filtered component for left panel + * + * @param component + * @param filteredComponent + */ + private void copyFieldsForLeftPanel(Component component, Component filteredComponent) { + + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + filteredComponent.setCategories(component.getCategories()); + filteredComponent.setComponentType(component.getComponentType()); + if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType()) + && ResourceTypeEnum.VL.equals(((ResourceMetadataDataDefinition) component + .getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType())) { + filteredComponent.setCapabilities(component.getCapabilities()); + filteredComponent.setRequirements(component.getRequirements()); + } + filteredComponent.setVersion(component.getVersion()); + filteredComponent.setDescription(component.getDescription()); + filteredComponent.setUniqueId(component.getUniqueId()); + filteredComponent.setIcon(component.getIcon()); + filteredComponent.setTags(component.getTags()); + // filteredComponent.setAllVersions(component.getAllVersions()); + filteredComponent.setLifecycleState(component.getLifecycleState()); + // filteredComponent.setHighestVersion(component.isHighestVersion()); + filteredComponent.setInvariantUUID(component.getInvariantUUID()); + filteredComponent.setUUID(component.getUUID()); + filteredComponent.setSystemName(component.getSystemName()); + filteredComponent.setName(component.getName()); + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) component; + Resource filteredResource = (Resource) filteredComponent; + filteredResource.setToscaResourceName(resource.getToscaResourceName()); + // filteredResource.setAbstract(resource.isAbstract()); + // filteredResource.setVendorName(resource.getVendorName()); + // filteredResource.setVendorRelease(resource.getVendorRelease()); + filteredResource.setResourceType(resource.getResourceType()); + } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) { + // Service service = (Service)component; + // Service filteredService = (Service)filteredComponent; + // filteredService.setDistributionStatus(service.getDistributionStatus()); + } + } + + private void copyFieldsForCatalog(Component component, Component filteredComponent) { + + ComponentTypeEnum componentTypeEnum = component.getComponentType(); + filteredComponent.setCategories(component.getCategories()); + filteredComponent.setComponentType(component.getComponentType()); + filteredComponent.setVersion(component.getVersion()); + filteredComponent.setDescription(component.getDescription()); + filteredComponent.setUniqueId(component.getUniqueId()); + filteredComponent.setIcon(component.getIcon()); + filteredComponent.setTags(component.getTags()); + // filteredComponent.setAllVersions(component.getAllVersions()); + filteredComponent.setLifecycleState(component.getLifecycleState()); + // filteredComponent.setHighestVersion(component.isHighestVersion()); + // filteredComponent.setInvariantUUID(component.getInvariantUUID()); + filteredComponent.setSystemName(component.getSystemName()); + filteredComponent.setName(component.getName()); + filteredComponent.setLastUpdateDate(component.getLastUpdateDate()); + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) component; + Resource filteredResource = (Resource) filteredComponent; + filteredResource.setToscaResourceName(resource.getToscaResourceName()); + // filteredResource.setAbstract(resource.isAbstract()); + // filteredResource.setVendorName(resource.getVendorName()); + // filteredResource.setVendorRelease(resource.getVendorRelease()); + filteredResource.setResourceType(resource.getResourceType()); + } else if (componentTypeEnum == ComponentTypeEnum.SERVICE) { + Service service = (Service) component; + Service filteredService = (Service) filteredComponent; + filteredService.setDistributionStatus(service.getDistributionStatus()); + } + } + + /** + * get components from cache of a given list ou unique ids. + * + * for each component data from cassandra, unzip the data if needed and + * deserialize the unzipped data to java object(Component). + * + * @param filteredResources + * @return ImmutableTripple or ActionStatus. | |-- components |-- dirty + * components - components with dirty flag = true. |-- set of non + * cached components + * + */ + private Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> getComponentsFull( + Set<String> filteredResources) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + List<Component> foundResources = new LinkedList<>(); + List<Component> foundDirtyResources = new LinkedList<>(); + Set<String> notFoundResources = new HashSet<>(); + ImmutableTriple<List<Component>, List<Component>, Set<String>> result = new ImmutableTriple<List<Component>, List<Component>, Set<String>>( + foundResources, foundDirtyResources, notFoundResources); + + long cassandraFetchStart = System.currentTimeMillis(); + List<String> uidsList = new ArrayList<>(); + uidsList.addAll(filteredResources); + Either<List<ComponentCacheData>, ActionStatus> componentsFromCache = componentCassandraDao + .getComponents(uidsList); + + long cassandraFetchEnd = System.currentTimeMillis(); + logger.debug("Fetch time from cassandara of all components took {} ms", + (cassandraFetchEnd - cassandraFetchStart)); + if (componentsFromCache.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache", + "Failed to fetch components from cache", ErrorSeverity.ERROR); + return Either.right(componentsFromCache.right().value()); + } + + List<ComponentCacheData> list = componentsFromCache.left().value(); + logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size())); + if (list != null && false == list.isEmpty()) { + + List<ComponentCacheData> filteredData = list.stream().filter(p -> filteredResources.contains(p.getId())) + .collect(Collectors.toList()); + logger.debug("Number of components filterd is {}", filteredData == null ? 0 : filteredData.size()); + + if (filteredData != null) { + long desStart = System.currentTimeMillis(); + + for (ComponentCacheData componentCacheData : filteredData) { + + logger.debug("Process uid {} from cache", componentCacheData.getId()); + + String compUid = componentCacheData.getId(); + + Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent( + componentCacheData); + + if (deserializeExt.isLeft()) { + Component component = deserializeExt.left().value(); + if (false == componentCacheData.getIsDirty()) { + foundResources.add(component); + } else { + foundDirtyResources.add(component); + } + } else { + notFoundResources.add(compUid); + } + + } + long desEnd = System.currentTimeMillis(); + logger.debug("Deserialization and unzip of {} components took {} ms", filteredData.size(), + (desEnd - desStart)); + } + } + List<String> foundResourcesUid = foundResources.stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + List<String> foundDirtyResourcesUid = foundDirtyResources.stream().map(p -> p.getUniqueId()) + .collect(Collectors.toList()); + logger.debug("Number of processed components from cache is {}", + (foundResourcesUid.size() + foundDirtyResourcesUid.size())); + Set<String> notCachedResources = filteredResources.stream() + .filter(p -> false == foundResourcesUid.contains(p) && false == foundDirtyResourcesUid.contains(p)) + .collect(Collectors.toSet()); + notFoundResources.addAll(notCachedResources); + + if (logger.isDebugEnabled()) { + logger.debug("Number of components fetched is {}", foundResources.size()); + logger.debug("Number of components fetched dirty is {}", foundDirtyResources.size()); + logger.debug("Number of components non cached is {}", notCachedResources.size()); + } + + return Either.left(result); + } + + private Either<? extends Component, Boolean> convertComponentCacheToComponent( + ComponentCacheData componentCacheData) { + + String compUid = componentCacheData.getId(); + + byte[] dataAsArray = componentCacheData.getDataAsArray(); + + if (true == componentCacheData.getIsZipped()) { + long startUnzip = System.nanoTime(); + dataAsArray = ZipUtil.unzip(dataAsArray); + long endUnzip = System.nanoTime(); + logger.trace("Unzip component {} took {} microsecond", compUid, (endUnzip - startUnzip) / 1000); + } + + long startDes = System.nanoTime(); + + Either<? extends Component, Boolean> deserializeExt = deserializeComponent(componentCacheData, dataAsArray); + + long endDes = System.nanoTime(); + logger.trace("Deserialize component {} took {} microsecond", compUid, (endDes - startDes) / 1000); + return deserializeExt; + } + + private Either<? extends Component, Boolean> deserializeComponent(ComponentCacheData componentCacheData, + byte[] dataAsArray) { + String type = componentCacheData.getType(); + NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(type); + + Either<? extends Component, Boolean> deserializeExt = Either.right(false); + switch (typeEnum) { + case Resource: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Resource.class, componentCacheData.getId()); + break; + case Service: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Service.class, componentCacheData.getId()); + break; + case Product: + deserializeExt = SerializationUtils.deserializeExt(dataAsArray, Product.class, componentCacheData.getId()); + break; + default: + break; + } + return deserializeExt; + } + + public Either<Component, ActionStatus> getComponent(String componentUid) { + + return getComponent(componentUid, null, Function.identity()); + + } + + public Either<Component, ActionStatus> getComponent(String componentUid, Long lastModificationTime) { + + return getComponent(componentUid, lastModificationTime, Function.identity()); + + } + + public boolean setComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum) { + + boolean result = false; + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return false; + } + + ComponentOperation componentOperation = getComponentOperation(nodeTypeEnum); + + if (componentOperation == null) { + return false; + } + + Either<Component, StorageOperationStatus> either = componentOperation.getComponent(componentUid, false); + if (either.isLeft()) { + Component component = either.left().value(); + result = saveComponent(componentUid, lastModificationTime, nodeTypeEnum, component); + } else { + logger.debug("Failed to get component {} of type {} from graph. Status is {}", componentUid, + nodeTypeEnum.name().toLowerCase(), either.right().value()); + } + + return result; + + } + + private boolean saveComponent(String componentUid, Long lastModificationTime, NodeTypeEnum nodeTypeEnum, + Component component) { + + logger.trace("Going to save component {} of type {} in cache", componentUid, nodeTypeEnum.name().toLowerCase()); + + boolean result = false; + + Either<byte[], Boolean> serializeExt = SerializationUtils.serializeExt(component); + if (serializeExt.isLeft()) { + byte[] serializedData = serializeExt.left().value(); + byte[] zipBytes; + try { + zipBytes = ZipUtil.zipBytes(serializedData); + ComponentCacheData componentCacheData = new ComponentCacheData(); + componentCacheData.setDataAsArray(zipBytes); + componentCacheData.setIsZipped(true); + componentCacheData.setId(componentUid); + componentCacheData.setModificationTime(new Date(lastModificationTime)); + componentCacheData.setType(component.getComponentType().name().toLowerCase()); + + CassandraOperationStatus status = componentCassandraDao.saveComponent(componentCacheData); + + if (status == CassandraOperationStatus.OK) { + result = true; + } + + } catch (IOException e) { + logger.debug("Failed to prepare component {} of type {} for cache", componentUid, + nodeTypeEnum.name().toLowerCase()); + if (logger.isTraceEnabled()) { + logger.trace("Failed to prepare component " + componentUid + " of type " + + nodeTypeEnum.name().toLowerCase() + " for cache"); + } + } + } else { + logger.debug("Failed to serialize component {} of type {} for cache", componentUid, + nodeTypeEnum.name().toLowerCase()); + } + return result; + } + + public boolean setComponent(Component component, NodeTypeEnum nodeTypeEnum) { + + boolean result = false; + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return false; + } + + String componentUid = component.getUniqueId(); + Long lastUpdateDate = component.getLastUpdateDate(); + + result = saveComponent(componentUid, lastUpdateDate, nodeTypeEnum, component); + + return result; + + } + + private ComponentOperation getComponentOperation(NodeTypeEnum nodeTypeEnum) { + ComponentOperation componentOperation = null; + switch (nodeTypeEnum) { + case Resource: + componentOperation = resourceOperation; + break; + case Service: + componentOperation = serviceOperation; + break; + case Product: + componentOperation = productOperation; + break; + default: + break; + } + return componentOperation; + } + + /** + * get components from cache of a given list ou unique ids. + * + * for each component data from cassandra, unzip the data if needed and + * deserialize the unzipped data to java object(Component). + * + * @param filteredResources + * @return ImmutableTripple or ActionStatus. | |-- components |-- set of non + * cached components + * + */ + private Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFull( + Map<String, Long> filteredResources) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + List<Component> foundResources = new LinkedList<>(); + Set<String> notFoundResources = new HashSet<>(); + ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<List<Component>, Set<String>>( + foundResources, notFoundResources); + + long cassandraFetchStart = System.currentTimeMillis(); + + Either<ImmutablePair<List<ComponentCacheData>, Set<String>>, ActionStatus> componentsFromCache = componentCassandraDao + .getComponents(filteredResources); + + long cassandraFetchEnd = System.currentTimeMillis(); + logger.debug("Fetch time from cassandara of all components took {} ms", + (cassandraFetchEnd - cassandraFetchStart)); + if (componentsFromCache.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("FetchFromCache", + "Failed to fetch components from cache", ErrorSeverity.ERROR); + return Either.right(componentsFromCache.right().value()); + } + + ImmutablePair<List<ComponentCacheData>, Set<String>> immutablePair = componentsFromCache.left().value(); + List<ComponentCacheData> list = immutablePair.getLeft(); + logger.debug("Number of components fetched from cassandra is {}", (list == null ? 0 : list.size())); + if (list != null && false == list.isEmpty()) { + + // List<ComponentCacheData> filteredData = list.stream().filter(p -> + // filteredResources.contains(p.getId())).collect(Collectors.toList()); + logger.debug("Number of components filterd is {}", list == null ? 0 : list.size()); + + if (list != null) { + long desStart = System.currentTimeMillis(); + + for (ComponentCacheData componentCacheData : list) { + + logger.debug("Process uid {} from cache", componentCacheData.getId()); + + String compUid = componentCacheData.getId(); + + Either<? extends Component, Boolean> deserializeExt = convertComponentCacheToComponent( + componentCacheData); + + if (deserializeExt.isLeft()) { + Component component = deserializeExt.left().value(); + foundResources.add(component); + } else { + notFoundResources.add(compUid); + } + + } + long desEnd = System.currentTimeMillis(); + logger.debug("Deserialization and unzip of {} components took {} ms", list.size(), (desEnd - desStart)); + } + } + logger.debug("Number of processed components from cache is {}", foundResources.size()); + + Set<String> notFoundInCache = immutablePair.getRight(); + notFoundResources.addAll(notFoundInCache); + + if (logger.isDebugEnabled()) { + logger.debug("Number of components fetched is {}", foundResources.size()); + logger.debug("Number of components non cached is {}", notFoundResources.size()); + } + + return Either.left(result); + } + + /** + * get components for catalog + * + * @param components + * @param componentTypeEnum + * @return + */ + public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsForCatalog( + Map<String, Long> components, ComponentTypeEnum componentTypeEnum) { + + if (false == isEnabled()) { + logger.debug("In getComponentsForCatalog for type {}. Cache is disabled.", + componentTypeEnum.name().toLowerCase()); + return Either.right(ActionStatus.NOT_ALLOWED); + } + logger.debug("In getComponentsForCatalog for type {}", componentTypeEnum.name().toLowerCase()); + + Function<List<Component>, List<Component>> filterFieldsFunc = x -> filterForCatalog(x); + + Map<String, Long> leftComponentsForSearch = new HashMap<>(); + leftComponentsForSearch.putAll(components); + + // get components from inmemory cache + List<Component> componentsFromMemory = null; + if (true == catalogInMemoryEnabled) { + componentsFromMemory = getDataFromInMemoryCache(components.keySet(), componentTypeEnum); + logger.debug("The number of components of type {} fetched from memory is {}", + componentTypeEnum.name().toLowerCase(), + componentsFromMemory == null ? 0 : componentsFromMemory.size()); + if (componentsFromMemory != null) { + List<String> ignoredComponents = new ArrayList<>(); + for (Component componentFromMem : componentsFromMemory) { + if (componentFromMem.getLastUpdateDate().longValue() != components + .get(componentFromMem.getUniqueId()).longValue()) { + // Ignore the component from memory + ignoredComponents.add(componentFromMem.getUniqueId()); + } + } + + logger.debug("Number of components from type {} ignored from memory cache is {}", + componentTypeEnum.name().toLowerCase(), ignoredComponents.size()); + // remove from memory result the components which are not valid + componentsFromMemory = componentsFromMemory.stream() + .filter(p -> false == ignoredComponents.contains(p.getUniqueId())).collect(Collectors.toList()); + // Remove from leftComponentsForSearch the valid components from + // memory + componentsFromMemory.forEach(p -> leftComponentsForSearch.remove(p.getUniqueId())); + + } + } else { + logger.debug("Catalog InMemory cache is disabled"); + } + + logger.debug("Number of components from type {} needed to fetch is {}", componentTypeEnum.name().toLowerCase(), + leftComponentsForSearch.size()); + + // get components from cassandra cache and filter each component + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> result = getComponents( + leftComponentsForSearch, filterFieldsFunc); + + if (result.isLeft()) { + // add inmemory components to the valid components(not dirty) + List<Component> foundComponents = result.left().value().getLeft(); + if (componentsFromMemory != null) { + foundComponents.addAll(componentsFromMemory); + } + if (true == catalogInMemoryEnabled) { + updateCatalogInMemoryCacheWithCertified(foundComponents, componentTypeEnum); + } + } + + return result; + } + + /** + * @param components + * - Map of <componentUniqueId, last update date> + * @param filterFieldsFunc + * @return + */ + public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponents(Map<String, Long> components, + Function<List<Component>, List<Component>> filterFieldsFunc) { + + if (false == isEnabled()) { + logger.debug("Component Cache is disabled"); + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFull = getComponentsFull( + components); + + if (componentsFull.isRight()) { + return Either.right(componentsFull.right().value()); + } + + ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFull.left().value(); + List<Component> foundResources = immutablePair.left; + Set<String> notFoundResources = immutablePair.right; + + List<Component> filterdFoundResources = filterFieldsFunc.apply(foundResources); + + ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<List<Component>, Set<String>>( + filterdFoundResources, notFoundResources); + + return Either.left(result); + + } + + /** + * get the component and its modification time from cache + * + * @param componentUid + * @param filterFieldsFunc + * @return + */ + public Either<ImmutablePair<Component, Long>, ActionStatus> getComponentAndTime(String componentUid, + Function<Component, Component> filterFieldsFunc) { + + Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> componentFromCache = getComponentFromCache( + componentUid, null, filterFieldsFunc); + + if (componentFromCache.isRight()) { + return Either.right(componentFromCache.right().value()); + } + + ImmutablePair<Component, ComponentCacheData> immutablePair = componentFromCache.left().value(); + + ImmutablePair<Component, Long> result = new ImmutablePair<Component, Long>(immutablePair.left, + immutablePair.right.getModificationTime().getTime()); + + return Either.left(result); + } + + private Either<ImmutablePair<Component, ComponentCacheData>, ActionStatus> getComponentFromCache( + String componentUid, Long lastModificationTime, Function<Component, Component> filterFieldsFunc) { + if (false == isEnabled()) { + return Either.right(ActionStatus.NOT_ALLOWED); + } + + Either<ComponentCacheData, ActionStatus> componentRes = componentCassandraDao.getComponent(componentUid); + + if (componentRes.isRight()) { + return Either.right(componentRes.right().value()); + } + + ComponentCacheData componentCacheData = componentRes.left().value(); + + if (lastModificationTime != null) { + long cacheCompModificationTime = componentCacheData.getModificationTime().getTime(); + if (lastModificationTime != cacheCompModificationTime) { + logger.debug( + "Component {} found in cache but its modification time {} does not match to the timestamp in cache {}.", + componentUid, lastModificationTime, cacheCompModificationTime); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } + + Either<? extends Component, Boolean> convertRes = convertComponentCacheToComponent(componentCacheData); + if (convertRes.isRight()) { + return Either.right(ActionStatus.CONVERT_COMPONENT_ERROR); + } + + Component component = convertRes.left().value(); + + Component filteredComponent = component; + if (filterFieldsFunc != null) { + filteredComponent = filterFieldsFunc.apply(component); + } + + ImmutablePair<Component, ComponentCacheData> result = new ImmutablePair<Component, ComponentCacheData>( + filteredComponent, componentCacheData); + + return Either.left(result); + } + + public ActionStatus deleteComponentFromCache(String id) { + if (false == isEnabled()) { + return ActionStatus.NOT_ALLOWED; + } + CassandraOperationStatus status = this.componentCassandraDao.deleteComponent(id); + if (CassandraOperationStatus.OK.equals(status)) { + return ActionStatus.OK; + } else { + logger.debug("delete component failed with error {}", status); + return ActionStatus.GENERAL_ERROR; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java new file mode 100644 index 0000000000..bc63b34fec --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache; + +import org.openecomp.sdc.be.model.operations.api.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; + +public class DaoInfo { + private IResourceOperation iResourceOperation; + private IServiceOperation iServiceOperation; + private IProductOperation iProductOperation; + private ComponentCache ComponentCache; + + public DaoInfo(IResourceOperation iResourceOperation, IServiceOperation iServiceOperation, + IProductOperation iProductOperation, org.openecomp.sdc.be.model.cache.ComponentCache componentCache) { + this.iResourceOperation = iResourceOperation; + this.iServiceOperation = iServiceOperation; + this.iProductOperation = iProductOperation; + ComponentCache = componentCache; + } + + public IResourceOperation getResourceOperation() { + return iResourceOperation; + } + + public IServiceOperation getServiceOperation() { + return iServiceOperation; + } + + public IProductOperation getProductOperation() { + return iProductOperation; + } + + public org.openecomp.sdc.be.model.cache.ComponentCache getComponentCache() { + return ComponentCache; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java new file mode 100644 index 0000000000..93249c914a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.jobs; + +import fj.data.Either; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.function.Function; + +/** + * Created by mlando on 9/7/2016. + */ +public class CheckAndUpdateJob extends Job { + private static Logger log = LoggerFactory.getLogger(CheckAndUpdateJob.class.getName()); + + public CheckAndUpdateJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + } + + @Override + public Object doWork() { + log.trace("starting work on job."); + log.trace("update cache for componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, nodeTypeEnum, + timestamp); + + try { + + // get from cache + Either<ImmutablePair<Component, Long>, ActionStatus> cacheResult = daoInfo.getComponentCache() + .getComponentAndTime(componentId, Function.identity()); + // if error while getting from cache abort and update + if (cacheResult.isRight()) { + // genral error + if (!ActionStatus.RESOURCE_NOT_FOUND.equals(cacheResult.right().value()) + && !ActionStatus.INVALID_CONTENT.equals(cacheResult.right().value())) { + log.debug("failed to get component:{} from cache error:{}", componentId, + cacheResult.right().value()); + return false; + } + // component not in cache put there + else { + return updateCache(componentId, nodeTypeEnum, timestamp); + } + } + ImmutablePair<Component, Long> recored = cacheResult.left().value(); + // the cache has allready been updated exit + if (this.timestamp < recored.getRight()) { + log.debug("job timestemp:{} is smaller then the cache timestamp:{} no update is needed.", + this.timestamp, recored.getRight()); + return false; + } + return updateCache(componentId, nodeTypeEnum, timestamp); + + } catch (Exception e) { + log.debug("an exception was encountered during CheckAndUpdateJob", e); + } finally { + daoInfo.getResourceOperation().getTitanGenericDao().commit(); + } + return false; + } + + /** + * @param componentId + * @param nodeTypeEnum + * @return + */ + private boolean updateCache(String componentId, NodeTypeEnum nodeTypeEnum, Long timestamp) { + // get component from cache + Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = getComponentMetaData(componentId, + nodeTypeEnum); + if (metaDataRes.isRight()) { + return false; + } + ComponentMetadataData metaData = metaDataRes.left().value(); + // the job time is older then the one on graph nothing to do there is a + // job that will handle this. + Long graphTimestamp = metaData.getMetadataDataDefinition().getLastUpdateDate(); + if (timestamp < graphTimestamp) { + log.debug( + "the job timestamp:{} is smaller then the graph timestamp:{}. exiting because another job will update the cache.", + timestamp, graphTimestamp); + return false; + } else { + // update cache + // get component from grath + Either<Component, StorageOperationStatus> componentRes = getOperationByType(nodeTypeEnum) + .getComponent(componentId, true); + if (componentRes.isRight()) { + log.debug("failed to get full component:{} from graph status:{}", componentId, + componentRes.right().value()); + return false; + } + Component component = componentRes.left().value(); + // store in cache + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + } + log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java new file mode 100644 index 0000000000..ac1a56f9db --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/20/2016. + */ +public class DeleteJob extends Job { + private static Logger log = LoggerFactory.getLogger(DeleteJob.class.getName()); + + public DeleteJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("delete component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + ActionStatus status = this.daoInfo.getComponentCache().deleteComponentFromCache(componentId); + if (!ActionStatus.OK.equals(status)) { + log.debug("failed to delete componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.trace("cache successfully deleted componentId:{} nodeTypeEnum:{} timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } catch (Exception e) { + log.debug("an exception was encountered durring deletejob", e); + } + return false; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java new file mode 100644 index 0000000000..4deda8642f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.IComponentOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class Job<E> { + private static Logger log = LoggerFactory.getLogger(Job.class.getName()); + protected DaoInfo daoInfo; + protected String componentId; + protected long timestamp; + protected NodeTypeEnum nodeTypeEnum; + + protected Job(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + this.daoInfo = daoInfo; + this.componentId = componentId; + this.timestamp = timestamp; + this.nodeTypeEnum = nodeTypeEnum; + } + + protected Job(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) { + this.daoInfo = daoInfo; + this.componentId = component.getUniqueId(); + this.timestamp = component.getLastUpdateDate(); + this.nodeTypeEnum = nodeTypeEnum; + } + + public abstract E doWork(); + + protected IComponentOperation getOperationByType(NodeTypeEnum nodeTypeEnum) { + IComponentOperation operation = null; + switch (nodeTypeEnum) { + case Product: + operation = daoInfo.getProductOperation(); + break; + case Service: + operation = daoInfo.getServiceOperation(); + break; + case Resource: + operation = daoInfo.getResourceOperation(); + break; + default: + log.error("unexpected NodeType received no matching operation found."); + } + return operation; + } + + protected Either<ComponentMetadataData, StorageOperationStatus> getComponentMetaData(String componentId, + NodeTypeEnum nodeTypeEnum) { + Either<ComponentMetadataData, StorageOperationStatus> metaDataRes = getOperationByType(nodeTypeEnum) + .getComponentByLabelAndId(componentId, nodeTypeEnum, ComponentMetadataData.class); + if (metaDataRes.isRight()) { + // in case we cant find the component on graph exit + if (StorageOperationStatus.NOT_FOUND.equals(metaDataRes.right().value())) { + log.debug("failed to locate component:{} on graph status:{}", componentId, metaDataRes.right().value()); + } else { + log.debug("failed to get component:{} from graph status:{}", componentId, metaDataRes.right().value()); + } + } + return metaDataRes; + } + + protected NodeTypeEnum getNodeTypeFromComponentType(ComponentTypeEnum type) { + NodeTypeEnum result = null; + switch (type) { + case PRODUCT: + result = NodeTypeEnum.Product; + break; + case RESOURCE: + result = NodeTypeEnum.Resource; + break; + case SERVICE: + result = NodeTypeEnum.Service; + break; + default: + + } + return result; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java new file mode 100644 index 0000000000..e9da68ea59 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.jobs; + +import fj.data.Either; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/20/2016. + */ +public class OverrideJob extends Job { + private static Logger log = LoggerFactory.getLogger(OverrideJob.class.getName()); + + public OverrideJob(DaoInfo daoInfo, String componentId, NodeTypeEnum nodeTypeEnum, long timestamp) { + super(daoInfo, componentId, nodeTypeEnum, timestamp); + + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("override component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + // get component from grath + Either<Component, StorageOperationStatus> componentRes = getOperationByType(nodeTypeEnum) + .getComponent(componentId, false); + if (componentRes.isRight()) { + log.debug("failed to get full component:{} from graph status:{}", componentId, + componentRes.right().value()); + return false; + } + Component component = componentRes.left().value(); + // store in cache + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.debug("cache successfully overrided componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + } catch (Exception e) { + log.debug("an exception was encountered during OverrideJob", e); + } finally { + this.daoInfo.getResourceOperation().getTitanGenericDao().commit(); + } + return false; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java new file mode 100644 index 0000000000..410a56a90e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.jobs; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.DaoInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Created by mlando on 9/11/2016. + */ +public class StoreJob extends Job { + private static Logger log = LoggerFactory.getLogger(StoreJob.class.getName()); + private Component component; + + public StoreJob(DaoInfo daoInfo, Component component, NodeTypeEnum nodeTypeEnum) { + super(daoInfo, component, nodeTypeEnum); + this.component = component; + } + + @Override + public Object doWork() { + try { + log.trace("starting work on job."); + log.trace("store component in cache, componentId:{} of nodeTypeEnum:{} with timestamp:{}.", componentId, + nodeTypeEnum, timestamp); + if (!this.daoInfo.getComponentCache().setComponent(component, nodeTypeEnum)) { + log.debug("failed to store componentId:{} nodeTypeEnum:", componentId, nodeTypeEnum); + return false; + } + log.debug("cache successfully updated for componentId:{} nodeTypeEnum:{} timestemp:{}.", componentId, + nodeTypeEnum, timestamp); + return true; + + } catch (Exception e) { + log.debug("an exception was encountered during StoreJob", e); + } + return false; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java new file mode 100644 index 0000000000..7d6ff49507 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.workers; + +import org.openecomp.sdc.be.model.cache.jobs.Job; +import org.openecomp.sdc.be.model.cache.workers.IWorker; +import org.openecomp.sdc.be.workers.Worker; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +/** + * Created by mlando on 9/6/2016. the class represents a worker the pull job + * from a queue and evacuates them. + * + */ +public class CacheWorker implements Runnable, IWorker { + private String workerName; + private static Logger log = LoggerFactory.getLogger(Worker.class.getName()); + private LinkedBlockingQueue<Job> jobQueue; + private volatile boolean shutdown = false; + + /** + * constructor + * + * @param workerName + * the name of the given worker + * @param jobQueue + * the queue the worker will block on. + */ + public CacheWorker(String workerName, LinkedBlockingQueue<Job> jobQueue) { + this.workerName = workerName; + this.jobQueue = jobQueue; + } + + /** + * the method will try to get a job if one is avilable it will be retrived + * and handled. if no jobs are available the worker will block for 500 + * milliseconds and then it wil check if it needs to shutdown. if not it + * will block again and so on until sutdown or a new job is available + */ + @Override + public void run() { + while (true) { + log.trace("CacheWorker:{} doing work", workerName); + try { + Job job = jobQueue.poll(500, TimeUnit.MILLISECONDS); + if (job != null) { + job.doWork(); + log.trace("worker:{} done with work", workerName); + } + } catch (Throwable e) { + log.debug("worker {} failed during job execution.", workerName); + log.debug("exception", e); + } + if (shutdown) { + log.debug("worker:{} nothing to do stoping", workerName); + break; + } + } + + } + + /** + * the method sets the shutdown flag, when set the worker will stop it's + * execution as soon as possible with out completing its work + */ + @Override + public void shutDown() { + this.shutdown = true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java new file mode 100644 index 0000000000..fcdf9f4148 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java @@ -0,0 +1,28 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.workers; + +/** + * Created by mlando on 9/6/2016. + */ +public interface IWorker { + void shutDown(); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java new file mode 100644 index 0000000000..824dd3496f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java @@ -0,0 +1,266 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.cache.workers; + +import fj.data.Either; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ComponentCacheData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.*; +import java.util.stream.Collectors; + +/** + * the class creates a worker that is used to update cache date, in case of + * failures and inconsistencies + */ +public class SyncWorker implements Runnable, IWorker { + + private static Logger log = LoggerFactory.getLogger(SyncWorker.class.getName()); + private final CacheMangerOperation cacheMangerOperation; + private final String workerName; + private volatile boolean shutdown = false; + private Map<String, ComponentCacheData> cacheIdAndTimeMap; + private long updateDelayInMilliseconds = 60 * 60 * 1000; + + /** + * creates the sync worker + * + * @param workerName + * the name of the worker + * @param cacheMangerOperation + * responsible for all persistence's operations to graph and the + * cache + */ + public SyncWorker(String workerName, CacheMangerOperation cacheMangerOperation) { + this.workerName = workerName; + this.cacheMangerOperation = cacheMangerOperation; + } + + /** + * the method collects all the resources/services/products from graph and + * checks if the component representing them in the cache is valid logic: if + * the record is present in the graph but not in cache -> create a job that + * will update the record oin cache if the timestamp of the record in cache + * is older than the timestamp on the graph -> create a job that will update + * the record oin cache otherwise no update is required + */ + @Override + public void run() { + try { + collectAllCacheRecords(); + syncCacheByComponentType(NodeTypeEnum.Resource); + syncCacheByComponentType(NodeTypeEnum.Service); + syncCacheByComponentType(NodeTypeEnum.Product); + clearCacheRecords(); + + } catch (Exception e) { + log.debug("sync worker:{} encounered an exception", workerName); + log.debug("exception", e); + } finally { + this.cacheMangerOperation.getTitanGenericDao().commit(); + } + } + + /** + * the method checks for each component in the cache except the ones that + * were update during the sync, if they exist on the graph if not a job to + * remove them is created + */ + private void clearCacheRecords() { + cacheIdAndTimeMap.forEach((k, v) -> { + try { + Either<ComponentMetadataData, TitanOperationStatus> componentFromGraphRes = getComponentMetaData(k, + NodeTypeEnum.getByName(v.getType())); + if (componentFromGraphRes.isRight()) { + TitanOperationStatus error = componentFromGraphRes.right().value(); + if (TitanOperationStatus.NOT_FOUND.equals(error)) { + long delay = System.currentTimeMillis() - v.getModificationTime().getTime(); + if (delay > updateDelayInMilliseconds) { + this.cacheMangerOperation.deleteComponentInCache(k, v.getModificationTime().getTime(), + NodeTypeEnum.getByName(v.getType())); + } else { + log.trace( + "no delete done because an hour did not pass since the delete was done timeSinceUpdate {} < updateDelayInMilliseconds {} ", + delay, updateDelayInMilliseconds); + } + } else { + log.debug("failed to get metadata for id:{} from graph error:{}", k, error); + } + } else { + log.trace("id {} is in graph nothing to do"); + } + } catch (Exception e) { + log.debug("during clean cache records an exception was thrown", e); + } + }); + } + + /** + * the method collects all the records from cache except the component + * itself + */ + public void collectAllCacheRecords() { + Either<List<ComponentCacheData>, ActionStatus> getAllRes = this.cacheMangerOperation.getComponentCache() + .getAllComponentIdTimeAndType(); + if (getAllRes.isRight()) { + log.debug("error while trying to get all records from cache error:{}", getAllRes.right().value()); + cacheIdAndTimeMap = new HashMap<>(); + } else { + cacheIdAndTimeMap = getAllRes.left().value().stream().collect(Collectors.toMap(e -> e.getId(), e -> e)); + } + } + + /** + * the method checks that the records ot the given type are sync between the + * cache and the graph + * + * @param nodeTypeEnum + * the type of components we want to sync + */ + private void syncCacheByComponentType(NodeTypeEnum nodeTypeEnum) { + if (!this.shutdown) { + log.trace("syncCache records of type:{} .", nodeTypeEnum); + Either<List<ComponentMetadataData>, TitanOperationStatus> getAllResult = getAllComponentsMetaData( + nodeTypeEnum); + List<ComponentMetadataData> componentList = new ArrayList<>(); + if (getAllResult.isRight() && !TitanOperationStatus.NOT_FOUND.equals(getAllResult.right().value())) { + log.debug("error while trying to get all components of type:{} TitanOperationStatus:{}.", nodeTypeEnum, + getAllResult.right().value()); + return; + } + if (getAllResult.isLeft()) { + componentList = getAllResult.left().value(); + log.trace("get all components of type:{} returned:{} components.", nodeTypeEnum, componentList.size()); + } + componentList.forEach(this::checkAndUpdateCacheComponent); + log.trace("syncCache records of type:{} was successful.", nodeTypeEnum); + } + } + + /** + * the method compares the given component to the record in the cache if the + * record is not in the cache a job to update the cache for this record will + * be created. if the record is present in the graph but not in cache -> + * create a job that will update the record oin cache if the timestamp of + * the record in cache is older than the timestamp on the graph -> create a + * job that will update the record oin cache if the retried component from + * cache fails to be deserialized -> create job to override it otherwise no + * update is required + * + * @param metadataData + * the date of the node we want to compare to the value in the + * cache + */ + private void checkAndUpdateCacheComponent(ComponentMetadataData metadataData) { + long timeSinceUpdate = System.currentTimeMillis() + - metadataData.getMetadataDataDefinition().getLastUpdateDate(); + if (timeSinceUpdate >= updateDelayInMilliseconds) { + String uid = metadataData.getMetadataDataDefinition().getUniqueId(); + log.trace("checking cache if record for uid:{} needs to be updated.", uid); + Either<Component, ActionStatus> cacheResult = this.cacheMangerOperation.getComponentCache() + .getComponent(uid); + if (cacheResult.isRight()) { + ActionStatus actionStatus = cacheResult.right().value(); + if (ActionStatus.RESOURCE_NOT_FOUND.equals(actionStatus)) { + log.trace("record for uid:{} not found in cache. creating an update job.", uid); + this.cacheMangerOperation.updateComponentInCache(uid, + metadataData.getMetadataDataDefinition().getLastUpdateDate(), + NodeTypeEnum.getByName(metadataData.getLabel())); + } else if (ActionStatus.CONVERT_COMPONENT_ERROR.equals(actionStatus)) { + log.trace("uid:{} found in cache but we failed deserializing it. creating an override job .", uid); + this.cacheMangerOperation.overideComponentInCache(uid, + metadataData.getMetadataDataDefinition().getLastUpdateDate(), + NodeTypeEnum.getByName(metadataData.getLabel())); + } else { + log.debug("during lookup for uid:{} an error accords status:{} .", uid, actionStatus); + } + } else { + log.trace("uid:{} found in cache.", uid); + this.cacheIdAndTimeMap.remove(uid); + Component cacheComponent = cacheResult.left().value(); + Long cacheTimestamp = cacheComponent.getLastUpdateDate(); + Long graphTimestamp = metadataData.getMetadataDataDefinition().getLastUpdateDate(); + if (cacheTimestamp < graphTimestamp) { + log.trace("uid:{} found in cache. cache Timestamp {} < graph timestamp , creating an update job .", + uid, cacheTimestamp, graphTimestamp); + this.cacheMangerOperation.updateComponentInCache(uid, graphTimestamp, + NodeTypeEnum.getByName(metadataData.getLabel())); + } else { + log.trace("uid:{} found in cache. cache Timestamp {} => graph timestamp , no update is needed .", + uid, cacheTimestamp, graphTimestamp); + } + } + } else { + log.trace( + "no update done because an hour did not pass since the update was done timeSinceUpdate {} < updateDelayInMilliseconds {} ", + timeSinceUpdate, updateDelayInMilliseconds); + } + } + + /** + * the method sets the shutdown flag, when set the worker will stop it's + * execution as soon as possible with out completing its work + */ + @Override + public void shutDown() { + log.debug("syncWorker {} shuting down.", workerName); + this.shutdown = true; + } + + /** + * the method retrives all nodes matching the given node type from the graph + * + * @param nodeTypeEnum + * node type we want to lookup on the graph + * @return a list of retrieved nodes matching the given type or not found in + * case no nodes were found or error in case of failure + */ + private Either<List<ComponentMetadataData>, TitanOperationStatus> getAllComponentsMetaData( + NodeTypeEnum nodeTypeEnum) { + return this.cacheMangerOperation.getTitanGenericDao().getByCriteria(nodeTypeEnum, null, + ComponentMetadataData.class); + } + + /** + * the method retrieves the metadata from graph for the given id + * + * @param uid + * the unique id of the component we want to retrieve + * @param nodeTypeEnum + * the type of the recored we want to retrieve + * @return the meta dat of the component or the error encountered during the + * get + */ + private Either<ComponentMetadataData, TitanOperationStatus> getComponentMetaData(String uid, + NodeTypeEnum nodeTypeEnum) { + return this.cacheMangerOperation.getTitanGenericDao().getNode(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), + uid, ComponentMetadataData.class); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java new file mode 100644 index 0000000000..9286344af6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.category; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; + +public class CategoryDefinition extends CategoryDataDefinition implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6552733796860992476L; + + List<SubCategoryDefinition> subcategories; + + public CategoryDefinition() { + super(); + } + + public CategoryDefinition(CategoryDataDefinition c) { + super(c); + } + + public List<SubCategoryDefinition> getSubcategories() { + return subcategories; + } + + public void setSubcategories(List<SubCategoryDefinition> subcategories) { + this.subcategories = subcategories; + } + + public void addSubCategory(SubCategoryDefinition subcategory) { + if (subcategories == null) { + subcategories = new ArrayList<SubCategoryDefinition>(); + } + subcategories.add(subcategory); + } + + @Override + public String toString() { + return super.toString() + " CategoryDefinition [subcategories=" + subcategories + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java new file mode 100644 index 0000000000..aeee0a8972 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.category; + +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; + +public class GroupingDefinition extends GroupingDataDefinition { + + public GroupingDefinition() { + super(); + } + + public GroupingDefinition(GroupingDataDefinition g) { + super(g); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java new file mode 100644 index 0000000000..14559a1354 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.category; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; + +public class SubCategoryDefinition extends SubCategoryDataDefinition { + + private List<GroupingDefinition> groupings; + + public SubCategoryDefinition() { + super(); + } + + public SubCategoryDefinition(SubCategoryDataDefinition subCategory) { + super(subCategory); + } + + public List<GroupingDefinition> getGroupings() { + return groupings; + } + + public void setGroupings(List<GroupingDefinition> groupingDefinitions) { + this.groupings = groupingDefinitions; + } + + public void addGrouping(GroupingDefinition groupingDefinition) { + if (groupings == null) { + groupings = new ArrayList<GroupingDefinition>(); + } + groupings.add(groupingDefinition); + } + + @Override + public String toString() { + return super.toString() + " SubCategoryDefinition [groupings=" + groupings + "]"; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java new file mode 100644 index 0000000000..7de0aa561d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.heat; + +import org.openecomp.sdc.be.model.tosca.converters.DefaultConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatBooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatCommaDelimitedListConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatJsonConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatNumberConverter; +import org.openecomp.sdc.be.model.tosca.converters.HeatStringConverter; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.StringConvertor; +import org.openecomp.sdc.be.model.tosca.validators.HeatBooleanValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatCommaDelimitedListValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatNumberValidator; +import org.openecomp.sdc.be.model.tosca.validators.HeatStringValidator; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; + +public enum HeatParameterType { + + STRING("string", HeatStringValidator.getInstance(), HeatStringConverter.getInstance()), + + BOOLEAN("boolean", HeatBooleanValidator.getInstance(), HeatBooleanConverter.getInstance()), + + NUMBER("number", HeatNumberValidator.getInstance(), HeatNumberConverter.getInstance()), + + JSON("json", HeatStringValidator.getInstance(), HeatJsonConverter.getInstance()), + + COMMA_DELIMITED_LIST("comma_delimited_list", HeatCommaDelimitedListValidator.getInstance(), HeatCommaDelimitedListConverter.getInstance()); + + private String type; + private PropertyTypeValidator validator; + private PropertyValueConverter converter; + + HeatParameterType(String type, PropertyTypeValidator validator, PropertyValueConverter converter) { + this.type = type; + this.validator = validator; + this.converter = converter; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public PropertyTypeValidator getValidator() { + return validator; + } + + public void setValidator(PropertyTypeValidator validator) { + this.validator = validator; + } + + public PropertyValueConverter getConverter() { + return converter; + } + + public void setConverter(PropertyValueConverter converter) { + this.converter = converter; + } + + public static HeatParameterType isValidType(String typeName) { + if (typeName == null) { + return null; + } + + for (HeatParameterType type : HeatParameterType.values()) { + if (type.getType().equals(typeName)) { + return type; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java new file mode 100644 index 0000000000..71167c395f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IAdditionalInformationOperation { + + public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value); + + public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String origKey, String key, String value); + + public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key); + + public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, + String resourceUniqueId); + + public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode( + NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters); + + public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, + List<AdditionalInformationDefinition> properties); + + public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, + List<AdditionalInformationDefinition> properties); + + public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction); + + public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction); + + public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction); + + public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, + String resourceId, boolean inTransaction); + + public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId); + + public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id); + + public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction); + + public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification); + + public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction); + + public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean inTransaction); + + public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId, TitanVertex matadatVertex); + + public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, + AdditionalInformationDefinition parameters, TitanVertex metadataVertex); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java new file mode 100644 index 0000000000..873d05e1ed --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.resources.data.ArtifactData; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IArtifactOperation { + + public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfExist, boolean inTransaction); + + public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction); + + public Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinition(ArtifactDefinition artifactInfo, boolean inTransaction); + + public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum resource, boolean deleteMandatoryArtifact, boolean inTransaction); + + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction); + + public void setTitanGenericDao(TitanGenericDao titanGenericDao); + + public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String id, boolean inTransaction); + + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, String groupType); + + Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String parentId, NodeTypeEnum parentType, boolean inTransaction); + + public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion); + + public Either<Integer, StorageOperationStatus> getParentsOfArtifact(String artifactId, NodeTypeEnum type); + + public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(String heatEnvId, boolean inTransaction); + + public Either<ArtifactData, StorageOperationStatus> updateToscaArtifactNameOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id); + + public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex); + + public Either<ArtifactData, StorageOperationStatus> getLatestArtifactDataByArtifactUUID(String artifactUUID, boolean inTransaction); + + StorageOperationStatus addArifactToComponent(TitanVertex artifactInfo, TitanVertex parentVertex, String label); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java new file mode 100644 index 0000000000..db2b988f5f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IAttributeOperation { + Either<AttributeData, StorageOperationStatus> deleteAttribute(String attributeId); + + TitanOperationStatus addAttributesToGraph(TitanVertex metadataVertex, Map<String, AttributeDefinition> attributes, String resourceId, Map<String, DataTypeDefinition> dataTypes); + + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> getAllAttributesOfResourceInstance(ComponentInstance compInstance); + + TitanOperationStatus findAllResourceAttributesRecursively(String resourceId, List<AttributeDefinition> attributes); + + Either<Map<String, AttributeDefinition>, StorageOperationStatus> deleteAllAttributeAssociatedToNode(NodeTypeEnum nodeType, String uniqueId); + + TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, NodeTypeEnum nodeType, List<AttributeDefinition> attributes); + + Either<AttributeData, StorageOperationStatus> addAttribute(AttributeDefinition attributeDefinition, String resourceId); + + Either<AttributeData, TitanOperationStatus> addAttributeToGraph(AttributeDefinition attribute, String resourceId, Map<String, DataTypeDefinition> dataTypes); + + AttributeDefinition convertAttributeDataToAttributeDefinition(AttributeData attributeData, String attributeName, String resourceId); + + Either<AttributeData, StorageOperationStatus> updateAttribute(String attributeId, AttributeDefinition newAttDef, Map<String, DataTypeDefinition> dataTypes); + + /** + * Builds ComponentInstanceAttribute from AttributeValueData + * + * @param attributeValueData + * @param resourceInstanceAttribute + * @return + */ + ComponentInstanceAttribute buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceAttribute resourceInstanceAttribute); + + TitanOperationStatus addAttributeToGraphByVertex(TitanVertex metadataVertex, AttributeDefinition attribute, String resourceId, Map<String, DataTypeDefinition> dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java new file mode 100644 index 0000000000..52586dad60 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.cache.jobs.CheckAndUpdateJob; +import org.openecomp.sdc.be.model.cache.jobs.StoreJob; + +/** + * Created by mlando on 9/5/2016. + */ +public interface ICacheMangerOperation { + + /** + * + * + * @param componentId + * @param timestamp + * @param nodeTypeEnum + */ + void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum); + + void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java new file mode 100644 index 0000000000..e50b658121 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java @@ -0,0 +1,143 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * public interface ICapabilityInstanceOperation provides methods for CRUD + * operations for CapabilityInstance on component instance level + * + * @author ns019t + * + */ +public interface ICapabilityInstanceOperation { + /** + * create capability instance of capability with property values for + * resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @param validateCapabilityInstExistance + * @param capabilityName + * @return + */ + public Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance( + String resourceInstanceId, String capabilityId, String capabilityName, + List<ComponentInstanceProperty> propertyValues, boolean validateCapabilityInstExistance); + + /** + * + * @param resourceInstanceVertex + * @param capabilityId + * @param capabilityName + * @param propertyValues + * @param validateCapabilityInstExistence + * @return + */ + public TitanOperationStatus createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance( + TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + List<ComponentInstanceProperty> propertyValues, boolean validateCapabilityInstExistence); + + /** + * validate capability instance uniqueness + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + public Either<Boolean, TitanOperationStatus> validateCapabilityInstExistence(String resourceInstanceId, + String capabilityId); + + /** + * delete capability instance from resource instance + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @return + */ + public Either<CapabilityInstData, TitanOperationStatus> deleteCapabilityInstanceFromResourceInstance( + String resourceInstanceId, String capabilityInstanceId); + + /** + * get all capability instances for resource instance returns all Capability + * Instances related to Resource Instance as List<CapabilityInstData> or + * TitanOperationStatus if error occurs or if Resource Instance have no any + * related Capability Instance + * + * @param resourceInstanceId + * @return Either<List<CapabilityInstData>, TitanOperationStatus> + */ + public Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getAllCapabilityInstancesOfResourceInstance( + String resourceInstanceId); + + /** + * get capability instance of capability for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + public Either<CapabilityInstData, TitanOperationStatus> getCapabilityInstanceOfCapabilityOfResourceInstance( + String resourceInstanceId, String capabilityId); + + /** + * update capability property values + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @param propertyValues + * @param capabilityId + * @return + */ + public Either<List<PropertyValueData>, TitanOperationStatus> updateCapabilityPropertyValues( + String resourceInstanceId, String capabilityId, List<ComponentInstanceProperty> propertyValues); + + /** + * clone and associate capability instance with property values + * + * @param createdComponentInstance + * @param capability + * @param capabilityInstPair + * @return + */ + public Either<ImmutablePair<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> cloneAssociateCapabilityInstanceWithPropertyValues( + ComponentInstanceData createdComponentInstance, CapabilityDefinition capability, + ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstPair); + + Either<Boolean, TitanOperationStatus> validateCapabilityInstExistence(TitanVertex instanceVertex, + String resourceInstanceId, String capabilityId); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java new file mode 100644 index 0000000000..3b692b9607 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.PropertyData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface ICapabilityOperation { + + public Either<CapabilityDefinition, StorageOperationStatus> addCapability(String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition); + + public Either<CapabilityDefinition, StorageOperationStatus> addCapability(String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition, boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String uniqueId); + + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String uniqueId, boolean inTransaction); + + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String capabilityName, String resourceId); + + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String capabilityName, String resourceId, + boolean inTransaction); + + public Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> getAllCapabilitiesPairs( + String resourceId); + + public Either<Map<String, CapabilityDefinition>, StorageOperationStatus> deleteAllCapabilities(String resourceId, + boolean inTransaction); + + public Either<CapabilityDefinition, TitanOperationStatus> getCapabilityByCapabilityData( + CapabilityData capabilityData); + + public TitanOperationStatus getCapabilitySourcesList(String resourceId, List<String> derivedFromList); + + public Either<Map<String, PropertyData>, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, + String capabilityType, List<PropertyDefinition> newProperties); + + public Either<Map<String, PropertyData>, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, + String capabilityType, List<PropertyDefinition> newProperties, boolean inTransaction); + + StorageOperationStatus addCapability(TitanVertex metadataVertex, String resourceId, String capabilityName, + CapabilityDefinition capabilityDefinition, boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java new file mode 100644 index 0000000000..6f0b5b8d13 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; + +import fj.data.Either; + +public interface ICapabilityTypeOperation { + + /** + * @param capabilityTypeDefinition + * @return + */ + public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition); + + public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId); + + public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, + boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java new file mode 100644 index 0000000000..e51e077906 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java @@ -0,0 +1,246 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; + +import fj.data.Either; + +public interface IComponentInstanceOperation { + + /** + * add resource instance to service + * + * @param containerComponentId + * - component id + * @param instanceNumber + * - instance number of the component instance + * @param componentInstance + * @param inTransaction + * @return + */ + public Either<ComponentInstance, StorageOperationStatus> createComponentInstance(String containerComponentId, + NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, + NodeTypeEnum instNodeType, boolean inTransaction); + + /** + * add resource instance to service with internal transaction + * + * @param containerComponentId + * @param instanceNumber + * @param componentInstance + * @return + */ + public Either<ComponentInstance, StorageOperationStatus> createComponentInstance(String containerComponentId, + NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, + NodeTypeEnum instNodeType); + + /** + * delete resource instance from component + * + * @param containerComponentId + * - containerComponent id + * @param resourceInstUid + * - resource instance uid + * @param inTransaction + * @return + */ + public Either<ComponentInstance, StorageOperationStatus> deleteComponentInstance(NodeTypeEnum containerNodeType, + String containerComponentId, String resourceInstUid, boolean inTransaction); + + public Either<ComponentInstance, StorageOperationStatus> deleteComponentInstance(NodeTypeEnum containerNodeType, + String containerComponentId, String resourceInstUid); + + /** + * associate 2 resource instances for a given requirement + * + * @param serviceId + * @param fromResInstanceUid + * @param toResInstanceUid + * @param requirement + * @param relationship + * @param inTransaction + * @return + */ + // public Either<RequirementCapabilityRelDef, StorageOperationStatus> + // associateResourceInstances( + // String serviceId, NodeTypeEnum nodeType, String fromResInstanceUid, + // String toResInstanceUid, String requirement, String relationship, + // boolean inTransaction); + + // public Either<RequirementCapabilityRelDef, StorageOperationStatus> + // associateResourceInstances( + // String serviceId, NodeTypeEnum nodeType, String fromResInstanceUid, + // String toResInstanceUid, String requirement, String relationship); + + public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef relation, boolean inTransaction); + + public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef relation); + + /** + * + * dissociate the relation between 2 resource instances for a given + * requirement + * + * @param serviceId + * @param fromResInstanceUid + * @param toResInstanceUid + * @param requirement + * @param inTransaction + * @return + */ + public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef, boolean inTransaction); + + public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String serviceId, + NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef); + + /** + * update the properties of a given resource instance + * + * @param serviceId + * @param resourceInstanceName + * @param resourceInstance + * @param inTransaction + * @return + */ + public Either<ComponentInstance, StorageOperationStatus> updateResourceInstance(String serviceId, + NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance, + boolean inTransaction); + + public Either<ComponentInstance, StorageOperationStatus> updateResourceInstance(String serviceId, + NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance); + + /** + * get all resource instances of a given service and the relations between + * the resource instances + * + * @param serviceId + * @param inTransaction + * @return + */ + public Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, StorageOperationStatus> getAllComponentInstances( + String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, boolean inTransaction); + + public Either<List<String>, StorageOperationStatus> getAllComponentInstancesNames(String componentId, + NodeTypeEnum nodeType, boolean inTransaction); + + public Either<List<String>, StorageOperationStatus> getAllComponentInstancesNames(String componentId, + NodeTypeEnum nodeType); + + /** + * get resource instance from id + * + * @param resourceId + * @return resource instance of given id + */ + public Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(String resourceId); + + public Either<List<ComponentInstance>, StorageOperationStatus> deleteAllComponentInstances(String serviceId, + NodeTypeEnum nodeType, boolean inTransaction); + + public Either<List<ComponentInstance>, StorageOperationStatus> deleteAllComponentInstances(String serviceId, + NodeTypeEnum nodeType); + + public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter( + String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction); + + public String createComponentInstLogicalName(String instanceNumber, String componentInstanceName); + + public Either<Boolean, StorageOperationStatus> isComponentInstanceNameExist(String parentComponentId, + NodeTypeEnum parentNodeType, String compInstId, String componentInstName); + + public Either<Boolean, StorageOperationStatus> validateParent(String parentId, String uniqId, + boolean inTransaction); + + public Either<ComponentInstance, StorageOperationStatus> getFullComponentInstance( + ComponentInstance componentInstance, NodeTypeEnum compInstNodeType); + + public Either<Boolean, StorageOperationStatus> isAvailableRequirement(ComponentInstance fromResInstance, + RequirementAndRelationshipPair relationPair); + + public Either<Boolean, StorageOperationStatus> isAvailableCapabilty(ComponentInstance toResInstance, + RequirementAndRelationshipPair relationPair); + + public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, + boolean inTransaction); + + public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isvalidate, + Integer index, boolean inTransaction); + + /** + * Adds Attribute to resource instance + * + * @param resourceInstanceAttribute + * * @param resourceInstanceId * @param index * @param + * inTransaction + * @return + **/ + public Either<ComponentInstanceAttribute, StorageOperationStatus> addAttributeValueToResourceInstance( + ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, Integer index, + boolean inTransaction); + + public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( + ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction); + + /** + * Updates Attribute on resource instance + * + * @param attribute + * @param resourceInstanceId + * @param inTransaction + * @return + */ + public Either<ComponentInstanceAttribute, StorageOperationStatus> updateAttributeValueInResourceInstance( + ComponentInstanceAttribute attribute, String resourceInstanceId, boolean inTransaction); + + public Either<AttributeValueData, TitanOperationStatus> createOrUpdateAttributeOfResourceInstance( + ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId); + + public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance( + ComponentInstanceInput input, String resourceInstanceId, Integer innerElement, boolean b); + + public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance( + ComponentInstanceInput input, String resourceInstanceId, boolean b); + + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> fetchCIEnvArtifacts( + String componentInstanceId); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java new file mode 100644 index 0000000000..e7eff13a9d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; + +import fj.data.Either; + +public interface IComponentOperation { + public <T extends Component> Either<T, StorageOperationStatus> getComponent(String id, Class<T> clazz); + + public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, + NodeTypeEnum parentType, boolean inTransacton); + + public <T> Either<T, StorageOperationStatus> getLightComponent(String id, boolean inTransaction); + + public <T> Either<T, StorageOperationStatus> getComponent(String id, boolean inTransaction); + + public <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, + boolean inTranscation); + + public <T extends GraphNode> Either<T, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, + NodeTypeEnum nodeType, Class<T> clazz); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java new file mode 100644 index 0000000000..290552b382 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.resources.data.ConsumerData; + +import fj.data.Either; + +public interface IConsumerOperation { + + /** + * the method updates the node in the graph with the given ConsumerData + * + * @param consumerData + * the object we want to store + * @param inTransaction + * inTransaction is the operation part of a transaction, in case + * the value is false the action will be committed in the end of + * the method + * @return the updated object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction); + + /** + * the method updates the node in the graph with the given ConsumerData + * + * @param consumerData + * the object we want to store + * @return the updated object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData); + + /** + * the method deletes the node with the given unique id + * + * @param consumerName + * the unique id by witch we will look up the credential we want + * to delete + * @param inTransaction + * inTransaction is the operation part of a transaction, in case + * the value is false the action will be committed in the end of + * the method + * @return the deleted object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction); + + /** + * the method deletes the node with the given unique id + * + * @param consumerName + * the unique id by witch we will look up the credential we want + * to delete + * @return the deleted object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName); + + /** + * the method creates a new nod in the grape representing the supplied + * credential object + * + * @param consumerData + * the object we want to store + * @param inTransaction + * is the operation part of a transaction, in case the value is + * false the action will be committed in the end of the method + * @return the newly stored object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction); + + /** + * the method creates a new nod in the grape representing the supplied + * credential object + * + * @param consumerData + * the object we want to store + * @return the newly stored object returned from the graph + */ + Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData); + + /** + * the method retrieves the credential for the given consumer name + * + * @param consumerName + * the unique id by witch we will look up the credential + * @return ConsumerData or the error received during the operation + */ + Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java new file mode 100644 index 0000000000..b7f1882b45 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +import fj.data.Either; + +public interface IDataTypeOperation { + + /** + * @param dataTypeDefinition + * @return + */ + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition); + + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, + boolean inTransaction); + + /** + * @param name + * @return + */ + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name); + + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java new file mode 100644 index 0000000000..a21c194060 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.resources.data.CategoryData; + +import fj.data.Either; + +public interface IElementOperation { + + Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories(); + + Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories(); + + Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories(); + + public Either<List<Tag>, ActionStatus> getAllTags(); + + public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes(); + + public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes(); + + public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes(); + + public Either<Integer, ActionStatus> getDefaultHeatTimeout(); + + public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getCategoryData(String name, + NodeTypeEnum type, Class<T> clazz); + + public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.category.CategoryData, StorageOperationStatus> getNewCategoryData( + String name, NodeTypeEnum type, Class<T> clazz); + + public Either<Map<String, String>, ActionStatus> getResourceTypesMap(); + + Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType); + + Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, + boolean inTransaction); + + Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId); + + Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId); + + Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName); + + Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, + NodeTypeEnum nodeType); + + Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, SubCategoryDefinition subCategory, + NodeTypeEnum nodeType, boolean inTransaction); + + Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, boolean inTransaction); + + Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId); + + Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, + String normalizedName); + + Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, String subCategoryNormName, + String parentCategoryId); + + Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, + NodeTypeEnum nodeType); + + Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId); + + Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId); + + Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, + String parentSubCategoryId); + + Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, + String groupingNormalizedName); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java new file mode 100644 index 0000000000..d065ce0b09 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; + +public interface IGraphLockOperation { + + public abstract StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType); + + public abstract StorageOperationStatus unlockComponentByName(String name, String componentId, + NodeTypeEnum nodeType); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java new file mode 100644 index 0000000000..4252ec0622 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.GroupData; + +import fj.data.Either; + +public interface IGroupOperation { + + // add full group to component + public Either<GroupData, TitanOperationStatus> addGroupToGraph(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition); + + public Either<GroupDefinition, StorageOperationStatus> addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition); + + public Either<GroupDefinition, StorageOperationStatus> addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition, boolean inTransaction); + + public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(NodeTypeEnum nodeTypeEnum, + String componentId, List<GroupDefinition> groups, boolean inTransaction); + + // get group + public Either<GroupDefinition, TitanOperationStatus> getGroupFromGraph(String uniqueId); + + public Either<GroupDefinition, StorageOperationStatus> getGroup(String uniqueId); + + public Either<GroupDefinition, StorageOperationStatus> getGroup(String uniqueId, boolean inTransaction); + + // get all groups under component + public Either<List<GroupDefinition>, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum); + + public Either<List<GroupDefinition>, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction); + + public Either<List<GroupDefinition>, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum); + + // delete all groups under component + public Either<List<GroupDefinition>, TitanOperationStatus> deleteAllGroupsFromGraph(String componentId, + NodeTypeEnum compTypeEnum); + + public Either<List<GroupDefinition>, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction); + + public Either<List<GroupDefinition>, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum); + + // Association + public Either<List<String>, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId, boolean inTransaction); + + public Either<List<String>, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId); + + public Either<List<String>, TitanOperationStatus> getAssociatedGroupsToComponentInstanceFromGraph( + String componentInstanceId); + + public StorageOperationStatus associateGroupsToComponentInstance(List<String> groups, String componentInstanceId, + String compInstName, boolean inTransaction); + + public StorageOperationStatus associateGroupsToComponentInstance(List<String> groups, String componentInstanceId, + String compInstName); + + public Either<List<GraphRelation>, TitanOperationStatus> associateGroupsToComponentInstanceOnGraph( + List<String> groups, String componentInstanceId, String compInstName); + + public Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String artifactId); + + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId, boolean inTransaction); + + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId); + + public TitanOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact); + + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction); + + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact); + + public boolean isGroupExist(String groupName, boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java new file mode 100644 index 0000000000..2b612579b6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.resources.data.GroupTypeData; + +import fj.data.Either; + +public interface IGroupTypeOperation { + + /** + * @param groupTypeDefinition + * @return + */ + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition); + + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, + boolean inTransaction); + + /** + * @param uniqueId + * @return + */ + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId); + + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction); + + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name); + + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String name, + boolean inTransaction); + + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, + String version); + + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String name, String version, + boolean inTransaction); + + public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java new file mode 100644 index 0000000000..f903b4fc41 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; + +import fj.data.Either; + +public interface IHeatParametersOperation { + + public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String resourceId, NodeTypeEnum nodeType); + + public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties); + + public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId); + + public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId); + + public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition heatParam); + + public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel); + + public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java new file mode 100644 index 0000000000..2f1f2a70cf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.InputsData; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IInputsOperation { + + Either<String, StorageOperationStatus> deleteInput(String inputId); + + Either<List<InputDefinition>, TitanOperationStatus> addInputsToGraph(String componentId, NodeTypeEnum nodeType, + Map<String, InputDefinition> inputs, Map<String, DataTypeDefinition> dataTypes); + + Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(String resourceId, NodeTypeEnum nodeType, + ComponentInstInputsMap componentInsInputs, Map<String, DataTypeDefinition> dataTypes); + + TitanOperationStatus findNodeNonInheretedInputs(String uniqueId, List<InputDefinition> inputs); + + Either<List<InputDefinition>, StorageOperationStatus> getInputsOfComponent(String compId, String fromName, + int amount); + + Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstance( + ComponentInstance compInstance); + + Either<Map<String, InputDefinition>, StorageOperationStatus> deleteAllInputsAssociatedToNode(NodeTypeEnum nodeType, + String uniqueId); + + // TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, + // NodeTypeEnum nodeType, List<AttributeDefinition> attributes); + + Either<InputsData, StorageOperationStatus> addInput(String inputName, InputDefinition inputDefinition, + String componentId, NodeTypeEnum nodeType); + + Either<InputsData, TitanOperationStatus> addInputToGraph(String propertyName, InputDefinition inputDefinition, + String componentId, NodeTypeEnum nodeType); + + Either<AttributeData, StorageOperationStatus> updateInput(String inputId, InputDefinition newInDef, + Map<String, DataTypeDefinition> dataTypes); + + TitanOperationStatus findAllResourceInputs(String uniqueId, List<InputDefinition> inputs); + + Either<InputDefinition, StorageOperationStatus> getInputById(String uniqueId, boolean skipProperties, + boolean skipinputsValue); + + TitanOperationStatus addInputsToGraph(TitanVertex metadata, String componentId, Map<String, InputDefinition> inputs, + Map<String, DataTypeDefinition> dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java new file mode 100644 index 0000000000..bbcb61fea8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.Map; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IInterfaceLifecycleOperation { + + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction); + + public StorageOperationStatus createInterfaceOnResource(InterfaceDefinition interf, String resourceId, + String interfaceName, boolean failIfExist, boolean inTransaction, TitanVertex metadataVertex); + + public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName); + + public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean inTransaction); + + // public Either<InterfaceDefinition, StorageOperationStatus> + // getInterface(String interfaceId); + // + // public Either<InterfaceDefinition, StorageOperationStatus> + // getInterface(String interfaceId, boolean inTransaction); + + public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf); + + public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf, boolean inTransaction); + + public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, + String operationName); + + public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, + String operationName, boolean inTransaction); + + public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively, boolean inTransaction); + + public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively); + + public Either<InterfaceDefinition, StorageOperationStatus> deleteInterfaceOfResourceOnGraph(String resourceId, + InterfaceDefinition interfaceDef, boolean inTransaction); + + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf); + + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, + boolean inTransaction); + + public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId); + + public StorageOperationStatus associateInterfaceToNode(GraphNode node, InterfaceDefinition interfaceDefinition, + TitanVertex metadataVertex); + + public Either<Operation, StorageOperationStatus> getSpecificOperation(String resourceId, String interfaceType, + String operationName); + + public Either<InterfaceDefinition, StorageOperationStatus> dissociateInterfaceFromNode(GraphNode node, + InterfaceDefinition interfaceDefinition); + + public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java new file mode 100644 index 0000000000..3b82eb692c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; + +import fj.data.Either; + +public interface ILifecycleOperation { + + public ResourceOperation getResourceOperation(); + + public Either<User, StorageOperationStatus> getComponentOwner(String resourceId, NodeTypeEnum nodeType, + boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> checkinComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> requestCertificationComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> startComponentCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> checkoutComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> certifyComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> cancelOrFailCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, LifecycleStateEnum nextState, boolean b); + + public Either<Boolean, StorageOperationStatus> deleteOldComponentVersions(NodeTypeEnum nodeType, + String componentName, String uuid, boolean inTransaction); + + public Either<? extends Component, StorageOperationStatus> undoCheckout(NodeTypeEnum nodeType, Component resource, + User modifier, User currentOwner, boolean inTransaction); + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java new file mode 100644 index 0000000000..fc689c81e2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import org.openecomp.sdc.be.model.PolicyTypeDefinition; + +import fj.data.Either; + +public interface IPolicyTypeOperation { + + Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String policyTypeName); + + Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyType); + + Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyType(String uniqueId, boolean inTransaction); + + Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyType, + boolean inTransaction); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java new file mode 100644 index 0000000000..bbfea262a7 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java @@ -0,0 +1,47 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Set; + +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; + +import fj.data.Either; + +public interface IProductOperation extends IComponentOperation { + public Either<List<Product>, StorageOperationStatus> getProductCatalogData(boolean inTransaction); + + public Either<Product, StorageOperationStatus> createProduct(Product product); + + public Either<Product, StorageOperationStatus> createProduct(Product product, boolean inTransaction); + + public Either<Product, StorageOperationStatus> deleteProduct(String productId, boolean inTransaction); + + public Either<List<Product>, StorageOperationStatus> getFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction); + + public void rollback(); + + public void commit(); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java new file mode 100644 index 0000000000..6309510f6d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java @@ -0,0 +1,110 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyDefinition; + +import fj.data.Either; + +public interface IPropertyOperation { + + /** + * add property to resource + * + * @param propertyName + * @param propertyDefinition + * @param nodeType + * @param id + * @return + * + * public Either<PropertyDefinition, StorageOperationStatus> + * addPropertyToResource( String propertyName, PropertyDefinition + * propertyDefinition, NodeTypeEnum nodeType, String id); + */ + + /** + * get property belongs to resource + * + * @param propertyName + * - property name + * @param resourceId + * - resource unique id + * @return + */ + public Either<PropertyDefinition, StorageOperationStatus> getPropertyOfResource(String propertyName, + String resourceId); + + /** + * Delete all properties of resource + * + * @param nodeType + * @param uniqueId + * @return + */ + public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode( + NodeTypeEnum nodeType, String uniqueId); + + public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, + Map<String, DataTypeDefinition> dataTypes); + + public boolean isPropertyTypeValid(IComplexDefaultValue propertyDefinition); + + public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue propertyDefinition, + Map<String, DataTypeDefinition> dataTypes); + + /** + * @param dataTypeDefinition + * @return + */ + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition); + + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, + boolean inTransaction); + + /** + * @param name + * @return + */ + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name); + + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction); + + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, + boolean inTransaction); + + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name); + + public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, + Map<String, DataTypeDefinition> dataTypes); + + public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, + DataTypeDefinition oldDataTypeDefinition, boolean inTransaction); + + public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, + DataTypeDefinition oldDataTypeDefinition); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java new file mode 100644 index 0000000000..a7a9bf6013 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.RequirementImplDef; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public interface IRequirementOperation { + + /** + * add a requirement to resource + * + * @param reqName + * @param reqDefinition + * @param nodeType + * @param uniqueId + * @return + */ + public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId); + + public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction); + + public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId); + + public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId, boolean inTransaction); + + /** + * get requirement of resource + * + * @param reqName + * @param resourceId + * @return + */ + public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName, + String resourceId); + + public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName, + String resourceId, boolean inTransaction); + + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> getAllResourceRequirements( + String resourceId, boolean inTransaction); + + Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> getAllRequirementsOfResourceOnly( + String resourceId, boolean inTransaction); + + public Either<Map<String, RequirementDefinition>, TitanOperationStatus> getResourceRequirements(String resourceId); + + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRequirements(String resourceId, + boolean inTransaction); + + public Either<RequirementDefinition, TitanOperationStatus> getRequirement(String uniqueId); + + StorageOperationStatus addRequirementToResource(TitanVertex metadataVertex, String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java new file mode 100644 index 0000000000..759380c236 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java @@ -0,0 +1,131 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; + +import fj.data.Either; + +public interface IResourceOperation extends IComponentOperation { + + public TitanGenericDao getTitanGenericDao(); + + // public StorageOperationStatus lockResource(Resource resource); + // + // public StorageOperationStatus unlockResource(Resource resource); + + public Either<Resource, StorageOperationStatus> createResource(Resource resource); + + public Either<Resource, StorageOperationStatus> createResource(Resource resource, boolean inTransaction); + + public Either<Resource, StorageOperationStatus> getResource(String resourceId); + + // public Either<Resource, StorageOperationStatus> getResource_tx(String + // resourceId,boolean inTransaction); + + public Either<Resource, StorageOperationStatus> getResource(String resourceId, boolean inTransaction); + + /** + * the method retrieves all the certified resources, the returned values are + * only abstract or only none abstract according to the supplied parameters. + * + * @param getAbstract + * the value defines which resources to return only abstract or + * only none abstract + * @return + */ + public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean getAbstract); + + public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean getAbstract, + Boolean isHighest); + + public Either<Boolean, StorageOperationStatus> validateResourceNameExists(String resourceName, + ResourceTypeEnum resourceType); + + public Either<Resource, StorageOperationStatus> deleteResource(String resourceId); + + public Either<Resource, StorageOperationStatus> deleteResource(String resourceId, boolean inTransaction); + + public Either<Resource, StorageOperationStatus> updateResource(Resource resource); + + public Either<Resource, StorageOperationStatus> updateResource(Resource resource, boolean inTransaction); + + public Either<Integer, StorageOperationStatus> getNumberOfResourcesByName(String resourceName); + + // public Either<List<ArtifactDefinition>, StorageOperationStatus> + // getResourceArtifactsForDelete(Resource resource); + + public Either<List<Resource>, StorageOperationStatus> getFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction); + + public Either<Set<Resource>, StorageOperationStatus> getCatalogData(Map<String, Object> propertiesToMatch, + boolean inTransaction); + + public Either<Resource, StorageOperationStatus> getLatestByName(String resourceName, boolean inTransaction); + + public Either<Resource, StorageOperationStatus> overrideResource(Resource resource, Resource resourceSaved, + boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getTesterFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceListByUuid(String uuid, boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceListBySystemName(String systemName, + boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceCatalogData(boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceCatalogDataVFLatestCertifiedAndNonCertified( + boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceByNameAndVersion(String name, String version, + boolean inTransaction); + + public Either<List<Resource>, StorageOperationStatus> getResourceByNameAndVersion(String name, String version); + + public Either<Resource, StorageOperationStatus> getResourceBySystemNameAndVersion(String name, String version, + Map<String, Object> additionalParams, boolean inTransaction); + + // public Either<List<Resource>, StorageOperationStatus> + // getAllNotCheckoutResources(boolean getAbstract); + + // public Either<List<Resource>, StorageOperationStatus> + // getAllNotCheckoutResources(boolean getAbstract, Boolean isHighest); + + public Either<List<String>, StorageOperationStatus> getAllResourcesMarkedForDeletion(); + + public Either<Boolean, StorageOperationStatus> isResourceInUse(String resourceToDelete); + + public Either<Resource, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName, + boolean inTransaction); + + public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExists(String templateName); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java new file mode 100644 index 0000000000..05eb7c66f6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; + +import fj.data.Either; + +public interface IServiceOperation extends IComponentOperation { + + public Either<Service, StorageOperationStatus> createService(Service service); + + public Either<Service, StorageOperationStatus> createService(Service service, boolean inTransaction); + + public Either<Service, StorageOperationStatus> getService(String uniqueId); + + public Either<Service, StorageOperationStatus> getService(String uniqueId, boolean inTransaction); + // public Either<Service, StorageOperationStatus> getService_tx(String + // uniqueId, boolean inTransaction); + + public Either<Service, StorageOperationStatus> deleteService(String uniqueId); + + public Either<Service, StorageOperationStatus> deleteService(String uniqueId, boolean inTransaction); + + public Either<Boolean, StorageOperationStatus> validateServiceNameExists(String serviceName); + + public Either<List<Service>, StorageOperationStatus> getFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction); + + public Either<Service, StorageOperationStatus> updateService(Service service, boolean inTransaction); + + public Either<Set<Service>, StorageOperationStatus> getCatalogData(Map<String, Object> propertiesToMatch, + boolean inTransaction); + + public Either<List<Service>, StorageOperationStatus> getTesterFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, boolean inTransaction); + + public Either<Set<Service>, StorageOperationStatus> getCertifiedServicesWithDistStatus( + Map<String, Object> propertiesToMatch, Set<DistributionStatusEnum> distStatus, boolean inTransaction); + + public Either<Service, StorageOperationStatus> updateDestributionStatus(Service service, User user, + DistributionStatusEnum distributionStatus); + + public Either<List<Service>, StorageOperationStatus> getServiceCatalogData(boolean inTransaction); + + public Either<List<Service>, StorageOperationStatus> getServiceCatalogDataLatestCertifiedAndNotCertified( + boolean inTransaction); + + public Either<Service, StorageOperationStatus> getServiceByNameAndVersion(String name, String version, + Map<String, Object> additionalParams, boolean inTransaction); + + public Either<Service, StorageOperationStatus> getServiceByNameAndVersion(String name, String version); + + public Either<Service, StorageOperationStatus> getServiceBySystemNameAndVersion(String name, String version, + boolean inTransaction); + + public Either<List<Service>, StorageOperationStatus> getServiceListByUuid(String uuid, boolean inTransaction); + + public Either<List<Service>, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean inTransaction); + + public Either<List<Service>, StorageOperationStatus> getServiceListBySystemName(String systemName, + boolean inTransaction); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java new file mode 100644 index 0000000000..dd9766fc83 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.User; + +import fj.data.Either; + +public interface IUserAdminOperation { + + public Either<User, ActionStatus> getUserData(String id, boolean inTransaction); + + public Either<User, ActionStatus> getInactiveUserData(String id); + + public Either<User, StorageOperationStatus> saveUserData(User user); + + public Either<User, StorageOperationStatus> updateUserData(User user); + + public Either<User, StorageOperationStatus> deActivateUser(User user); + + public Either<User, ActionStatus> deleteUserData(String id); + + public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status); + + public Either<List<Edge>, StorageOperationStatus> getUserPandingTasksList(User user, + Map<String, Object> properties); + + public Either<ImmutablePair<User, FunctionalMenuInfo>, ActionStatus> getUserDataWithFunctionalMenu(String userId); + + public Either<FunctionalMenuInfo, TitanOperationStatus> createOrUpdateFunctionalMenu(String userId, + String newFunctionalMenu); +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java new file mode 100644 index 0000000000..c2346a316a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.api; + +public enum StorageOperationStatus { + + OK, CONNECTION_FAILURE, BAD_REQUEST, ENTITY_ALREADY_EXISTS, GRAPH_IS_LOCK, GENERAL_ERROR, USER_NOT_FOUND, PERMISSION_ERROR, HTTP_PROTOCOL_ERROR, STORAGE_NOT_AVAILABLE, READ_ONLY_STORAGE, STORAGE_LEGACY_INDEX_ERROR, SCHEMA_ERROR, TRANSACTION_ERROR, EXEUCTION_FAILED, NOT_FOUND, OPERATION_NOT_SUPPORTED, CATEGORY_NOT_FOUND, PARENT_RESOURCE_NOT_FOUND, MULTIPLE_PARENT_RESOURCE_FOUND, INCONSISTENCY, GRAPH_IS_NOT_AVAILABLE, SCHEMA_VIOLATION, FAILED_TO_LOCK_ELEMENT, INVALID_ID, MATCH_NOT_FOUND, ARTIFACT_NOT_FOUND, DISTR_ENVIRONMENT_NOT_AVAILABLE, DISTR_ENVIRONMENT_NOT_FOUND, DISTR_ENVIRONMENT_SENT_IS_INVALID, DISTR_ARTIFACT_NOT_FOUND, OVERLOAD, INVALID_TYPE, INVALID_VALUE, INVALID_INNER_TYPE, CSAR_NOT_FOUND, GROUP_INVALID_CONTENT, CANNOT_UPDATE_EXISTING_ENTITY, PROPERTY_NAME_ALREADY_EXISTS, INVALID_PROPERTY,; + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java new file mode 100644 index 0000000000..c4bbaf58f6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java @@ -0,0 +1,413 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Supplier; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.reflect.TypeToken; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public abstract class AbstractOperation { + private static Logger log = LoggerFactory.getLogger(AbstractOperation.class.getName()); + @javax.annotation.Resource + protected TitanGenericDao titanGenericDao; + public static final String EMPTY_VALUE = null; + + protected Gson gson = new Gson(); + + @javax.annotation.Resource + protected ApplicationDataTypeCache applicationDataTypeCache; + + protected DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + protected <SomeData extends GraphNode, SomeDefenition> Either<SomeData, TitanOperationStatus> addDefinitionToNodeType(SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType, + Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) { + String defName = defNameGenerator.get(); + log.debug("Got {} {}", defName, someDefinition); + + SomeData someData = dataBuilder.get(); + + log.debug("Before adding {} to graph. data = {}", defName, someData); + + @SuppressWarnings("unchecked") + Either<SomeData, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData, (Class<SomeData>) someData.getClass()); + + log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData); + + if (eitherSomeData.isRight()) { + TitanOperationStatus operationStatus = eitherSomeData.right().value(); + log.error("Failed to add {} to graph. status is {}", defName, operationStatus); + return Either.right(operationStatus); + } + UniqueIdData uniqueIdData = new UniqueIdData(nodeType, nodeUniqueId); + log.debug("Before associating {} to {}.", uniqueIdData, defName); + + Either<GraphRelation, TitanOperationStatus> eitherRelations = titanGenericDao.createRelation(uniqueIdData, eitherSomeData.left().value(), edgeType, null); + if (eitherRelations.isRight()) { + TitanOperationStatus operationStatus = eitherRelations.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + return Either.left(eitherSomeData.left().value()); + } + + protected <SomeData extends GraphNode, SomeDefenition> TitanOperationStatus addDefinitionToNodeType(TitanVertex vertex, SomeDefenition someDefinition, NodeTypeEnum nodeType, String nodeUniqueId, final GraphEdgeLabels edgeType, + Supplier<SomeData> dataBuilder, Supplier<String> defNameGenerator) { + String defName = defNameGenerator.get(); + log.debug("Got {} {}", defName, someDefinition); + + SomeData someData = dataBuilder.get(); + + log.debug("Before adding {} to graph. data = {}", defName, someData); + + @SuppressWarnings("unchecked") + Either<TitanVertex, TitanOperationStatus> eitherSomeData = titanGenericDao.createNode(someData); + + log.debug("After adding {} to graph. status is = {}", defName, eitherSomeData); + + if (eitherSomeData.isRight()) { + TitanOperationStatus operationStatus = eitherSomeData.right().value(); + log.error("Failed to add {} to graph. status is {}", defName, operationStatus); + return operationStatus; + } + + TitanOperationStatus relations = titanGenericDao.createEdge(vertex, eitherSomeData.left().value(), edgeType, null); + if (!relations.equals(TitanOperationStatus.OK)) { + TitanOperationStatus operationStatus = relations; + BeEcompErrorManager.getInstance().logInternalFlowError("AddDefinitionToNodeType", "Failed to associate" + nodeType.getName() + " " + nodeUniqueId + "to " + defName + "in graph. status is " + operationStatus, ErrorSeverity.ERROR); + return operationStatus; + } + return relations; + } + + interface NodeElementFetcher<ElementDefinition> { + TitanOperationStatus findAllNodeElements(String nodeId, List<ElementDefinition> listTofill); + } + + public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) { + + if (log.isTraceEnabled()) + log.trace("Going to fetch elements under resource {}", resourceId); + TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements); + + if (resourceAttributesStatus != TitanOperationStatus.OK) { + return resourceAttributesStatus; + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher); + + if (addParentIntStatus != TitanOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR); + + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + protected <T, TStatus> void handleTransactionCommitRollback(boolean inTransaction, Either<T, TStatus> result) { + if (!inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + public <ElementTypeDefinition> Either<ElementTypeDefinition, StorageOperationStatus> getElementType(Function<String, Either<ElementTypeDefinition, TitanOperationStatus>> elementGetter, String uniqueId, boolean inTransaction) { + Either<ElementTypeDefinition, StorageOperationStatus> result = null; + try { + + Either<ElementTypeDefinition, TitanOperationStatus> ctResult = elementGetter.apply(uniqueId); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on element uniqueId:" + uniqueId + ". status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + handleTransactionCommitRollback(inTransaction, result); + + } + + } + + /** + * @param propertyDefinition + * @return + */ + + protected StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + String value = propertyDefinition.getDefaultValue(); + + ToscaPropertyType type = getType(propertyType); + + if (type == null) { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + if (dataTypeDefinition == null) { + log.debug("The type {} of property cannot be found.", propertyType); + return StorageOperationStatus.INVALID_TYPE; + } + + StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes); + + return status; + + } + String innerType = null; + + Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema()); + if (checkInnerType.isRight()) { + return StorageOperationStatus.INVALID_TYPE; + } + innerType = checkInnerType.left().value(); + + log.trace("After validating property type {}", propertyType); + + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(value)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(value)) { + String convertedValue = converter.convert(value, innerType, dataTypes); + propertyDefinition.setDefaultValue(convertedValue); + } + return StorageOperationStatus.OK; + } + + protected ToscaPropertyType getType(String propertyType) { + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + return type; + + } + + protected boolean isValidValue(ToscaPropertyType type, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + if (isEmptyValue(value)) { + return true; + } + + PropertyTypeValidator validator = type.getValidator(); + + boolean isValid = validator.isValid(value, innerType, dataTypes); + if (true == isValid) { + return true; + } else { + return false; + } + + } + + public boolean isEmptyValue(String value) { + if (value == null) { + return true; + } + return false; + } + + public boolean isNullParam(String value) { + if (value == null) { + return true; + } + return false; + } + + protected StorageOperationStatus validateAndUpdateComplexValue(IComplexDefaultValue propertyDefinition, String propertyType, + + String value, DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> dataTypes) { + + ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes); + + if (validateResult.right.booleanValue() == false) { + log.debug("The value {} of property from type {} is invalid", value, propertyType); + return StorageOperationStatus.INVALID_VALUE; + } + + JsonElement jsonElement = validateResult.left; + + log.trace("Going to update value in property definition {} {}", propertyDefinition.getName(), (jsonElement != null ? jsonElement.toString() : null)); + + updateValue(propertyDefinition, jsonElement); + + return StorageOperationStatus.OK; + } + + protected void updateValue(IComplexDefaultValue propertyDefinition, JsonElement jsonElement) { + + propertyDefinition.setDefaultValue(getValueFromJsonElement(jsonElement)); + + } + + protected String getValueFromJsonElement(JsonElement jsonElement) { + String value = null; + + if (jsonElement == null || jsonElement.isJsonNull()) { + value = EMPTY_VALUE; + } else { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + + return value; + } + + protected Either<String, TitanOperationStatus> getInnerType(ToscaPropertyType type, Supplier<SchemaDefinition> schemeGen) { + String innerType = null; + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + + SchemaDefinition def = schemeGen.get();// propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exists", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + return Either.left(innerType); + } + + /** + * Convert Constarint object to json in order to add it to the Graph + * + * @param constraints + * @return + */ + public List<String> convertConstraintsToString(List<PropertyConstraint> constraints) { + + List<String> result = null; + + if (constraints != null && false == constraints.isEmpty()) { + result = new ArrayList<String>(); + for (PropertyConstraint propertyConstraint : constraints) { + String constraint = gson.toJson(propertyConstraint); + result.add(constraint); + } + + } + + return result; + } + + public List<PropertyConstraint> convertConstraints(List<String> constraints) { + + if (constraints == null || constraints.size() == 0) { + return null; + } + + List<PropertyConstraint> list = new ArrayList<PropertyConstraint>(); + Type constraintType = new TypeToken<PropertyConstraint>() { + }.getType(); + + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + + for (String constraintJson : constraints) { + PropertyConstraint propertyConstraint = gson.fromJson(constraintJson, constraintType); + list.add(propertyConstraint); + } + + return list; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java new file mode 100644 index 0000000000..e2c7f369f1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java @@ -0,0 +1,960 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.AdditionalInfoParameterDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AdditionalInfoParameterData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.util.AutoPopulatingList.ElementFactory; + +import fj.data.Either; + +@Component("additional-information-operation") +public class AdditionalInformationOperation implements IAdditionalInformationOperation { + + public static final String EMPTY_VALUE = null; + public static final String PROPERTY = "property"; + + public AdditionalInformationOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(AdditionalInformationOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @Override + public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String key, String value) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + if (parameters == null) { + parameters = new HashMap<String, String>(); + parameterData.setParameters(parameters); + } + Map<String, String> idToKey = parameterData.getIdToKey(); + if (idToKey == null) { + idToKey = new HashMap<String, String>(); + parameterData.setIdToKey(idToKey); + } + + Integer lastCreatedCounter = parameterData.getAdditionalInfoParameterDataDefinition().getLastCreatedCounter(); + lastCreatedCounter++; + + if (parameters.containsKey(key)) { + log.debug("The key {} already exists under component {}", key, componentId); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + idToKey.put(String.valueOf(lastCreatedCounter), key); + parameters.put(key, value); + parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter); + + Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "UpdateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + @Override + public Either<AdditionalInformationDefinition, TitanOperationStatus> updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id, String key, String value) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + Map<String, String> idToKey = parameterData.getIdToKey(); + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String origKey = idToKey.get(id); + + if (false == origKey.equals(key)) { + if (parameters.containsKey(key)) { + log.debug("The key {} already exists", key); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + String removed = parameters.remove(origKey); + log.trace("The key-value " + origKey + "=" + removed + " was removed from additionalInformation"); + } + parameters.put(key, value); + idToKey.put(id, key); + + Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "UpdateAdditionalInformationParameter", "additional information of resource " + componentId, + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("UpdateAdditionalInformationParameter", + "additional information of resource " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + @Override + public Either<AdditionalInformationDefinition, TitanOperationStatus> deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + Map<String, String> idToKey = parameterData.getIdToKey(); + + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String key = idToKey.get(id); + String removedKey = idToKey.remove(id); + String removedValue = parameters.remove(key); + log.trace("The key-value " + removedKey + "=" + removedValue + " was removed from additionalInformation"); + + Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "DeleteAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("DeleteAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + return Either.right(status); + } + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, updateNode.left().value()); + + return Either.left(informationDefinition); + + } + + private AdditionalInformationDefinition createInformationDefinitionFromNode(String resourceId, + Map<String, String> parameters, Map<String, String> idToKey, + AdditionalInfoParameterData additionalInfoParameterData) { + AdditionalInfoParameterDataDefinition dataDefinition = additionalInfoParameterData + .getAdditionalInfoParameterDataDefinition(); + + AdditionalInformationDefinition informationDefinition = new AdditionalInformationDefinition(dataDefinition, + resourceId, convertParameters(parameters, idToKey)); + return informationDefinition; + } + + private List<AdditionalInfoParameterInfo> convertParameters(Map<String, String> parameters, + Map<String, String> idToKey) { + + List<AdditionalInfoParameterInfo> list = new ArrayList<AdditionalInfoParameterInfo>(); + + if (parameters != null) { + for (Entry<String, String> idToKeyEntry : idToKey.entrySet()) { + + String id = idToKeyEntry.getKey(); + String key = idToKeyEntry.getValue(); + + String value = parameters.get(key); + + AdditionalInfoParameterInfo parameterInfo = new AdditionalInfoParameterInfo(id, key, value); + list.add(parameterInfo); + } + + } + + return list; + } + + @Override + public Either<AdditionalInfoParameterData, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId) { + + UniqueIdData from = new UniqueIdData(nodeType, componentId); + + String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId); + AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition(); + additionalInfoParameterDataDefinition.setUniqueId(uniqueId); + + AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData( + additionalInfoParameterDataDefinition, new HashMap<String, String>(), new HashMap<String, String>()); + + Either<AdditionalInfoParameterData, TitanOperationStatus> createNode = titanGenericDao + .createNode(additionalInfoParameterData, AdditionalInfoParameterData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, + "AddAdditionalInformationNode", + "additional information to " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, + String.valueOf(status)); + return Either.right(status); + } + + AdditionalInfoParameterData to = createNode.left().value(); + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, + GraphEdgeLabels.ADDITIONAL_INFORMATION, null); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + return Either.right(status); + } + + return Either.left(to); + } + + @Override + public Either<TitanVertex, TitanOperationStatus> addAdditionalInformationNode(NodeTypeEnum nodeType, + String componentId, TitanVertex metadataVertex) { + + String uniqueId = UniqueIdBuilder.buildAdditionalInformationUniqueId(componentId); + AdditionalInfoParameterDataDefinition additionalInfoParameterDataDefinition = new AdditionalInfoParameterDataDefinition(); + additionalInfoParameterDataDefinition.setUniqueId(uniqueId); + + AdditionalInfoParameterData additionalInfoParameterData = new AdditionalInfoParameterData( + additionalInfoParameterDataDefinition, new HashMap<String, String>(), new HashMap<String, String>()); + + Either<TitanVertex, TitanOperationStatus> createNode = titanGenericDao.createNode(additionalInfoParameterData); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, + "AddAdditionalInformationNode", + "additional information to " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("AddAdditionalInformationNode", uniqueId, + String.valueOf(status)); + return Either.right(status); + } + + TitanVertex additionalInfoVertex = createNode.left().value(); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, additionalInfoVertex, + GraphEdgeLabels.ADDITIONAL_INFORMATION, null); + + if (!createRelation.equals(TitanOperationStatus.OK)) { + return Either.right(createRelation); + } + return Either.left(additionalInfoVertex); + } + + public Either<AdditionalInformationDefinition, TitanOperationStatus> addAdditionalInformationNode( + NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition parameters) { + + Either<AdditionalInfoParameterData, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, + componentId); + + if (status.isRight()) { + return Either.right(status.right().value()); + } + + AdditionalInfoParameterData parameterData = status.left().value(); + + populateParameterNodeWithParameters(parameterData, parameters); + + Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } + + AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition( + updateNode.left().value(), componentId); + + return Either.left(informationDefinition); + } + + public TitanOperationStatus addAdditionalInformationNode(NodeTypeEnum nodeType, String componentId, + AdditionalInformationDefinition parameters, TitanVertex metadataVertex) { + + Either<TitanVertex, TitanOperationStatus> status = this.addAdditionalInformationNode(nodeType, componentId, + metadataVertex); + + if (status.isRight()) { + return status.right().value(); + } + TitanVertex additionalInfoVertex = status.left().value(); + + Map<String, Object> newProp = titanGenericDao.getProperties(additionalInfoVertex); + AdditionalInfoParameterData parameterData = GraphElementFactory.createElement( + NodeTypeEnum.AdditionalInfoParameters.getName(), GraphElementTypeEnum.Node, newProp, + AdditionalInfoParameterData.class); + + populateParameterNodeWithParameters(parameterData, parameters); + + TitanOperationStatus updateNode = titanGenericDao.updateVertex(parameterData, additionalInfoVertex); + + return updateNode; + } + + private void populateParameterNodeWithParameters(AdditionalInfoParameterData parameterData, + AdditionalInformationDefinition aiDefinition) { + + if (aiDefinition != null) { + + Integer lastCreatedCounter = aiDefinition.getLastCreatedCounter(); + parameterData.getAdditionalInfoParameterDataDefinition().setLastCreatedCounter(lastCreatedCounter); + log.trace("Set last created counter of additional information to " + lastCreatedCounter); + + List<AdditionalInfoParameterInfo> parameters = aiDefinition.getParameters(); + if (parameters != null) { + + Map<String, String> idToKey = new HashMap<String, String>(); + Map<String, String> parametersMap = new HashMap<String, String>(); + for (AdditionalInfoParameterInfo additionalInfoParameterInfo : parameters) { + String uniqueId = additionalInfoParameterInfo.getUniqueId(); + String key = additionalInfoParameterInfo.getKey(); + String value = additionalInfoParameterInfo.getValue(); + + if (key != null && false == key.isEmpty()) { + idToKey.put(uniqueId, key); + parametersMap.put(key, value); + } + } + parameterData.setIdToKey(idToKey); + parameterData.setParameters(parametersMap); + } + } + + } + + @Override + public TitanOperationStatus findResourceAllAdditionalInformationRecursively(String uniqueId, + List<AdditionalInformationDefinition> properties) { + + log.trace("Going to fetch additional information under resource " + uniqueId); + TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Resource, + uniqueId, properties); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.error("Failed to find parent additional information of resource " + uniqueId + ". status is " + + parentNodesStatus); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findResourceAllAdditionalInformationRecursively(parentUniqueId, + properties); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to find all resource additional information of resource " + parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + + } + + @Override + public TitanOperationStatus findServiceAllAdditionalInformationRecursively(String uniqueId, + List<AdditionalInformationDefinition> properties) { + + log.trace("Going to fetch additional information under service " + uniqueId); + TitanOperationStatus resourceCapabilitiesStatus = findAdditionalInformationOfNode(NodeTypeEnum.Service, + uniqueId, properties); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either<ImmutablePair<ServiceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Service, ServiceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (false == parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.error("Failed to find parent additional information of resource " + uniqueId + ". status is " + + parentNodesStatus); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair<ServiceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findServiceAllAdditionalInformationRecursively(parentUniqueId, + properties); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to find all resource additional information of resource " + parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus findAdditionalInformationOfNode(NodeTypeEnum nodeType, String uniqueId, + List<AdditionalInformationDefinition> properties) { + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> childNode = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ADDITIONAL_INFORMATION, + NodeTypeEnum.AdditionalInfoParameters, AdditionalInfoParameterData.class); + + if (childNode.isRight()) { + TitanOperationStatus status = childNode.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = childNode.left().value(); + AdditionalInfoParameterData propertyData = immutablePair.getKey(); + + Map<String, String> parameters = propertyData.getParameters(); + if (parameters != null && false == parameters.isEmpty()) { + AdditionalInformationDefinition additionalInfoDef = this + .convertAdditionalInformationDataToDefinition(propertyData, uniqueId); + properties.add(additionalInfoDef); + } + + return TitanOperationStatus.OK; + + } + + private AdditionalInformationDefinition convertAdditionalInformationDataToDefinition( + AdditionalInfoParameterData additionalInfoData, String uniqueId) { + + Map<String, String> parameters = additionalInfoData.getParameters(); + Map<String, String> idToKey = additionalInfoData.getIdToKey(); + + AdditionalInformationDefinition definition = new AdditionalInformationDefinition( + additionalInfoData.getAdditionalInfoParameterDataDefinition(), uniqueId, + convertParameters(parameters, idToKey)); + return definition; + } + + @Override + public Either<AdditionalInformationDefinition, StorageOperationStatus> createAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String key, String value, boolean inTransaction) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> result = null; + + try { + + Either<AdditionalInformationDefinition, TitanOperationStatus> either = this + .addAdditionalInformationParameter(nodeType, resourceId, key, value); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + log.debug("Failed to add additional information property {} to component {}. Status is {}", key, resourceId, status); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, + "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("CreateAdditionalInformationParameter", + "additional information of " + nodeType.getName() + " " + resourceId, String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either<AdditionalInformationDefinition, StorageOperationStatus> updateAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, String key, String value, boolean inTransaction) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> result = null; + + try { + + Either<AdditionalInformationDefinition, TitanOperationStatus> either = this + .updateAdditionalInformationParameter(nodeType, resourceId, id, key, value); + + if (either.isRight()) { + log.info("Failed to update additional information property " + key + " to component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> result = null; + + try { + + Either<AdditionalInformationDefinition, TitanOperationStatus> either = this + .deleteAdditionalInformationParameter(nodeType, resourceId, id); + + if (either.isRight()) { + log.error("Failed to delete additional information id " + id + " to component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + @Override + public Either<Integer, StorageOperationStatus> getNumberOfAdditionalInformationParameters(NodeTypeEnum nodeType, + String resourceId, boolean inTransaction) { + + Either<Integer, StorageOperationStatus> result = null; + + try { + + Either<Integer, TitanOperationStatus> either = this.getNumberOfParameters(nodeType, resourceId); + + if (either.isRight()) { + log.error("Failed to get the number of additional information properties in component " + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + Integer counter = either.left().value(); + result = Either.left(counter); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<Integer, TitanOperationStatus> getNumberOfParameters(NodeTypeEnum nodeType, String resourceId) { + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + + Integer counter = 0; + if (parameters != null) { + counter = parameters.size(); + } + + return Either.left(counter); + + } + + @Override + public Either<AdditionalInfoParameterInfo, TitanOperationStatus> getAdditionalInformationParameter( + NodeTypeEnum nodeType, String componentId, String id) { + + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + Map<String, String> idToKey = parameterData.getIdToKey(); + + if (idToKey == null || false == idToKey.containsKey(id)) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + String key = idToKey.get(id); + String value = parameters.get(key); + + log.trace("The key-value " + key + "=" + value + " was retrieved for id " + id); + + Either<AdditionalInfoParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(parameterData, + AdditionalInfoParameterData.class); + + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedRetrieveNodeError, + "GetAdditionnalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameter", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + } + return Either.right(status); + } + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(id, key, value); + + return Either.left(additionalInfoParameterInfo); + + } + + @Override + public Either<AdditionalInformationDefinition, TitanOperationStatus> getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String componentId, boolean ignoreVerification) { + + if (false == ignoreVerification) { + TitanOperationStatus verifyNodeTypeVsComponent = verifyNodeTypeVsComponent(nodeType, componentId); + if (verifyNodeTypeVsComponent != TitanOperationStatus.OK) { + return Either.right(verifyNodeTypeVsComponent); + } + } + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedRetrieveNodeError, + "GetAdditionnalInformationParameters", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("GetAdditionnalInformationParameters", + "additional information of " + nodeType.getName() + " " + componentId, String.valueOf(status)); + } + return Either.right(status); + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> immutablePair = getResult.left().value(); + AdditionalInfoParameterData parameterData = immutablePair.getLeft(); + Map<String, String> parameters = parameterData.getParameters(); + Map<String, String> idToKey = parameterData.getIdToKey(); + + AdditionalInformationDefinition informationDefinition = createInformationDefinitionFromNode(componentId, + parameters, idToKey, parameterData); + + return Either.left(informationDefinition); + + } + + @Override + public Either<AdditionalInformationDefinition, StorageOperationStatus> getAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean ignoreVerification, boolean inTransaction) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> result = null; + + try { + + Either<AdditionalInformationDefinition, TitanOperationStatus> either = this + .getAllAdditionalInformationParameters(nodeType, resourceId, ignoreVerification); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + + } + + private void commitOrRollback(boolean inTransaction, Either<? extends Object, StorageOperationStatus> result) { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + private void commitOrRollbackTx(TitanTransaction tx, boolean inTransaction, + Either<? extends Object, StorageOperationStatus> result) { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + tx.rollback(); + } else { + log.debug("Going to execute commit on graph."); + tx.commit(); + } + } + } + + @Override + public Either<AdditionalInfoParameterInfo, StorageOperationStatus> getAdditionalInformationParameter( + NodeTypeEnum nodeType, String resourceId, String id, boolean inTransaction) { + + Either<AdditionalInfoParameterInfo, StorageOperationStatus> result = null; + + try { + + Either<AdditionalInfoParameterInfo, TitanOperationStatus> either = this + .getAdditionalInformationParameter(nodeType, resourceId, id); + + if (either.isRight()) { + log.error("Failed to fetch additional information property with id " + id + " of component " + + resourceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value())); + } else { + AdditionalInfoParameterInfo additionalInformationDefinition = either.left().value(); + result = Either.left(additionalInformationDefinition); + } + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + } + + @Override + public Either<AdditionalInformationDefinition, StorageOperationStatus> deleteAllAdditionalInformationParameters( + NodeTypeEnum nodeType, String resourceId, boolean inTransaction) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> result = null; + + try { + + Either<ImmutablePair<AdditionalInfoParameterData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, + GraphEdgeLabels.ADDITIONAL_INFORMATION, NodeTypeEnum.AdditionalInfoParameters, + AdditionalInfoParameterData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.OK); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, + "DeleteAdditionalInformationNode", + "additional information of " + nodeType.getName() + " " + resourceId, + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", + "additional information of " + nodeType.getName() + " " + resourceId, + String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + return result; + } + + ImmutablePair<AdditionalInfoParameterData, GraphEdge> value = getResult.left().value(); + AdditionalInfoParameterData parameterData = value.getLeft(); + + Either<AdditionalInfoParameterData, TitanOperationStatus> deleteNodeRes = titanGenericDao + .deleteNode(parameterData, AdditionalInfoParameterData.class); + if (deleteNodeRes.isRight()) { + TitanOperationStatus status = getResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, + "DeleteAdditionalInformationNode", (String) parameterData.getUniqueId(), + String.valueOf(status)); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("DeleteAdditionalInformationNode", + (String) parameterData.getUniqueId(), String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + AdditionalInformationDefinition informationDefinition = convertAdditionalInformationDataToDefinition( + deleteNodeRes.left().value(), resourceId); + + result = Either.left(informationDefinition); + + return result; + + } finally { + commitOrRollback(inTransaction, result); + } + } + + private TitanOperationStatus verifyNodeTypeVsComponent(NodeTypeEnum nodeType, String componentId) { + Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao + .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexByProperty.isRight()) { + TitanOperationStatus status = vertexByProperty.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } else { + Vertex v = vertexByProperty.left().value(); + String label = (String) v.property(GraphPropertiesDictionary.LABEL.getProperty()).value(); + if (label != null) { + if (false == label.equals(nodeType.getName())) { + log.debug("The node type {} is not appropriate to component {}", nodeType, componentId); + return TitanOperationStatus.INVALID_ID; + } + } else { + log.debug("The node type {} with id {} does not have a label property.", nodeType, componentId); + return TitanOperationStatus.INVALID_ID; + } + } + return TitanOperationStatus.OK; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java new file mode 100644 index 0000000000..c005176238 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import org.springframework.stereotype.Component; + +@Component("all-operations") +public class AllOperationsUtil { + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private RequirementOperation requirementOperation; + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + public PropertyOperation getPropertyOperation() { + return propertyOperation; + } + + public RequirementOperation getRequirementOperation() { + return requirementOperation; + } + + public CapabilityOperation getCapabilityOperation() { + return capabilityOperation; + } + + public ResourceOperation getResourceOperation() { + return resourceOperation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java new file mode 100644 index 0000000000..a4f4bebd5a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java @@ -0,0 +1,1202 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Direction; +//import com.tinkerpop.blueprints.Edge; +//import com.tinkerpop.blueprints.Vertex; +//import com.tinkerpop.blueprints.util.ElementHelper; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("artifact-operation") +public class ArtifactOperation implements IArtifactOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @javax.annotation.Resource + private HeatParametersOperation heatParametersOperation; + + @javax.annotation.Resource + private GroupOperation groupOperation; + + private static Logger log = LoggerFactory.getLogger(ArtifactOperation.class.getName()); + + public ArtifactOperation() { + super(); + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public HeatParametersOperation getHeatParametersOperation() { + return heatParametersOperation; + } + + public void setHeatParametersOperation(HeatParametersOperation heatParametersOperation) { + this.heatParametersOperation = heatParametersOperation; + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, boolean inTransaction) { + + Either<ArtifactData, StorageOperationStatus> status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to add artifact {} to {} {}", artifactInfo.getArtifactName(), type, parentId); + return Either.right(status.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + + } + + @Override + public StorageOperationStatus addArifactToComponent(TitanVertex artifactInfo, TitanVertex parentVertex, String label) { + + // save logical artifact ref name on edge as property + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), label); + String groupInfo = (String) titanGenericDao.getProperty(artifactInfo, GraphPropertiesDictionary.ARTIFACT_GROUP_TYPE.getProperty()); + if (groupInfo != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), groupInfo); + TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactInfo, GraphEdgeLabels.ARTIFACT_REF, properties); + if (!relation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create relation in graph from id {} to new artifact {}", parentVertex, label); + return DaoStatusConverter.convertTitanStatusToStorageStatus(relation); + } + return StorageOperationStatus.OK; + + } + + @Override + public StorageOperationStatus addArifactToComponent(ArtifactDefinition artifactInfo, String parentId, NodeTypeEnum type, boolean failIfExist, TitanVertex parentVertex) { + + StorageOperationStatus status = addArtifactToGraph(artifactInfo, parentId, type, failIfExist, parentVertex); + + if (status.equals(StorageOperationStatus.OK)) { + log.debug("Failed to add artifact {} {} to {}", artifactInfo.getArtifactName(), type, parentId); + } + return status; + } + + private StorageOperationStatus addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist, TitanVertex parentVertex) { + + if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) { + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + } + + if (validateParentType(type) == false) { + return StorageOperationStatus.GENERAL_ERROR; + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either<TitanVertex, TitanOperationStatus> existArtifact = titanGenericDao.getVertexByProperty(artifactData.getUniqueIdKey(), artifactData.getUniqueId()); + if (existArtifact.isRight()) { + if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + // create new node + log.debug("Before adding artifact to graph {}", artifactData); + if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty()) + updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion()); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, "Failed to add artifact " + artifactData.getArtifactDataDefinition().getArtifactName() + " to graph. status is " + operationStatus, + artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus); + } + + // add heat parameters + if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef); + if (addPropertiesStatus != StorageOperationStatus.OK) { + log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName()); + return addPropertiesStatus; + } + } + + } else { + log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value()); + } + } else if (failIfexist) { + log.debug("Artifact {} already exist", artifactData.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST); + } + + // save logical artifact ref name on edge as property + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel()); + if (artifactInfo.getArtifactGroupType() != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType()); + TitanOperationStatus relation = titanGenericDao.createEdge(parentVertex, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties); + if (!relation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create relation in graph for id {} to new artifact", id); + return DaoStatusConverter.convertTitanStatusToStorageStatus(relation); + } + + return StorageOperationStatus.OK; + } + + private Either<ArtifactData, StorageOperationStatus> addArtifactToGraph(ArtifactDefinition artifactInfo, String id, NodeTypeEnum type, boolean failIfexist) { + + if (artifactInfo.getUniqueId() == null || artifactInfo.getUniqueId().isEmpty()) { + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + } + + if (validateParentType(type) == false) { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either<ArtifactData, TitanOperationStatus> existArtifact = titanGenericDao.getNode(artifactData.getUniqueIdKey(), artifactData.getUniqueId(), ArtifactData.class); + if (existArtifact.isRight()) { + if (existArtifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + // create new node + log.debug("Before adding artifact to graph {}", artifactData); + if (artifactData.getArtifactDataDefinition().getArtifactUUID() == null || artifactData.getArtifactDataDefinition().getArtifactUUID().isEmpty()) + updateUUID(artifactData.getArtifactDataDefinition(), null, artifactData.getArtifactDataDefinition().getArtifactVersion()); + Either<ArtifactData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(artifactData, ArtifactData.class); + log.debug("After adding artifact to graph {}", artifactData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.debug("Failed to add artifact {} to graph. status is {}", artifactData.getArtifactDataDefinition().getArtifactName(), operationStatus); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedCreateNodeError, "Failed to add artifact " + artifactData.getArtifactDataDefinition().getArtifactName() + " to graph. status is " + operationStatus, + artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add artifact", artifactData.getArtifactDataDefinition().getArtifactName(), String.valueOf(operationStatus)); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + } + artifactData = createNodeResult.left().value(); + + // add heat parameters + if (artifactInfo.getHeatParameters() != null && !artifactInfo.getHeatParameters().isEmpty() && !artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + StorageOperationStatus addPropertiesStatus = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactData.getUniqueId().toString(), NodeTypeEnum.ArtifactRef); + if (addPropertiesStatus != StorageOperationStatus.OK) { + log.debug("Failed to create heat parameters on graph for artifact {}", artifactInfo.getArtifactName()); + return Either.right(addPropertiesStatus); + } + } + + } else { + log.debug("Failed to check existance of artifact in graph for id {}", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(existArtifact.right().value())); + } + } else if (failIfexist) { + log.debug("Artifact {} already exist", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.ALREADY_EXIST)); + } else { + artifactData = existArtifact.left().value(); + } + + UniqueIdData parent = new UniqueIdData(type, id); + + // save logical artifact ref name on edge as property + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(GraphEdgePropertiesDictionary.NAME.getProperty(), artifactInfo.getArtifactLabel()); + if (artifactInfo.getArtifactGroupType() != null) + properties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), artifactInfo.getArtifactGroupType().getType()); + Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation(parent, artifactData, GraphEdgeLabels.ARTIFACT_REF, properties); + if (relation.isRight()) { + log.debug("Failed to create relation in graph for id {} to new artifact", id); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relation.right().value())); + } + + return Either.left(artifactData); + } + + private boolean validateParentType(NodeTypeEnum type) { + boolean isValid = false; + switch (type) { + case Resource: + case InterfaceOperation: + case Service: + case ResourceInstance: + isValid = true; + break; + default: + log.debug("Not supported node type for artifact relation : {}", type); + } + return isValid; + } + + protected ArtifactDefinition convertArtifactDataToArtifactDefinition(ArtifactData artifactDefResult) { + log.debug("The object returned after create property is {}", artifactDefResult); + + ArtifactDefinition propertyDefResult = new ArtifactDefinition(artifactDefResult.getArtifactDataDefinition()); + List<HeatParameterDefinition> parameters = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus heatParametersOfNode = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefResult.getUniqueId().toString(), parameters); + if ((heatParametersOfNode.equals(StorageOperationStatus.OK)) && !parameters.isEmpty()) { + propertyDefResult.setHeatParameters(parameters); + } + return propertyDefResult; + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> updateArifactOnResource(ArtifactDefinition artifactInfo, String id, String artifactId, NodeTypeEnum type, boolean inTransaction) { + Either<ArtifactData, StorageOperationStatus> status = updateArtifactOnGraph(artifactInfo, artifactId, type, id); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + if (log.isDebugEnabled()){ + log.debug("Failed to update artifact {} of {} {}. Status is {}", artifactId, type.getName(), id, status.right().value()); + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, "Failed to update artifact " + artifactId + " of " + type.getName() + " " + id + ". status is" + status.right().value(), artifactId, + String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactId, String.valueOf(status.right().value())); + return Either.right(status.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> updateArifactDefinition(ArtifactDefinition artifactInfo, boolean inTransaction) { + Either<ArtifactData, TitanOperationStatus> status = updateArifactDataDefinition(artifactInfo); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to update artifact {}", artifactInfo.getUniqueId()); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedUpdateNodeError, "Failed to update artifact " + artifactInfo.getUniqueId() + ". status is" + status.right().value(), artifactInfo.getUniqueId(), + String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedUpdateNodeError("Update Artifact", artifactInfo.getUniqueId(), String.valueOf(status.right().value())); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + private Either<ArtifactData, TitanOperationStatus> updateArifactDataDefinition(ArtifactDefinition artifactInfo) { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + + Either<ArtifactData, TitanOperationStatus> status = titanGenericDao.updateNode(artifactData, ArtifactData.class); + + if (status.isRight()) { + return Either.right(status.right().value()); + + } + return Either.left(status.left().value()); + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource(String id, String artifactId, NodeTypeEnum type, boolean deleteMandatoryArtifact, boolean inTransaction) { + Either<ArtifactData, TitanOperationStatus> status = removeArtifactOnGraph(id, artifactId, type, id, deleteMandatoryArtifact); + + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.debug("Failed to delete artifact {} of resource {}", artifactId, id); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedDeleteNodeError, "Failed to delete artifact " + artifactId + " of resource " + id, artifactId, String.valueOf(status.right().value())); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete Artifact", artifactId, String.valueOf(status.right().value())); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + ArtifactData artifactData = status.left().value(); + + ArtifactDefinition artifactDefResult = convertArtifactDataToArtifactDefinition(artifactData); + log.debug("The returned ArtifactDefintion is {}", artifactDefResult); + return Either.left(artifactDefResult); + } + } + + public Either<ArtifactData, StorageOperationStatus> updateToscaArtifactNameOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) { + return updateArtifactOnGraph(artifactInfo, artifactId, type, id); + } + + @SuppressWarnings("null") + private Either<ArtifactData, StorageOperationStatus> updateArtifactOnGraph(ArtifactDefinition artifactInfo, String artifactId, NodeTypeEnum type, String id) { + + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + + TitanGraph tGraph = graph.left().value(); + + @SuppressWarnings("unchecked") + Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + TitanVertex artifactV = iterator.next(); + + Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + int edgeCount = 0; + Edge edgeFromTo = null; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + Vertex vertexFrom = edge.outVertex(); + String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type)); + if (id.equals(vertexId)) { + edgeFromTo = edge; + } + ++edgeCount; + } + + ArtifactData artifactData = new ArtifactData(artifactInfo); + if (edgeFromTo == null) { + log.debug("No relation between artifact = {} and node with id = {}", artifactId, id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Either<Boolean, StorageOperationStatus> setRelevantHeatParamIdRes = null; + if (edgeCount > 1) { + // need to remove relation, create new node + log.debug("artifactRef have more connection. Need to clone node"); + log.debug("remove edge {}", edgeFromTo); + edgeFromTo.remove(); + // update resource id in new artifact node + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId(id, artifactInfo.getArtifactLabel()); + artifactInfo.setUniqueId(uniqueId); + // update UUID and artifact version + String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty())); + String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty())); + updateUUID(artifactInfo, oldChecksum, oldVersion); + log.debug("try to create new artifact ref node for id {}", uniqueId); + Either<ArtifactData, StorageOperationStatus> addedArtifactRes = addArtifactToGraph(artifactInfo, id, type, true); + + if (addedArtifactRes.isLeft()) { + // remove all relations between groups to the old artifact + // add relation between the same groups to the new artifact + StorageOperationStatus reassociateGroupsFromArtifact = groupOperation.dissociateAndAssociateGroupsFromArtifact(id, type, artifactId, addedArtifactRes.left().value(), true); + if (reassociateGroupsFromArtifact != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdateArtifact", "Failed to reassociate groups to the new artifact", ErrorSeverity.ERROR); + return Either.right(reassociateGroupsFromArtifact); + } + // If artifact is heat env + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + ArtifactData addedArtifact = addedArtifactRes.left().value(); + String newArtifactUniqueId = (String) addedArtifact.getUniqueId(); + Either<HeatParameterValueData, StorageOperationStatus> updateResult = null; + + setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo); + if (setRelevantHeatParamIdRes.isRight()) { + log.error("Failed to set relevant id to heat parameters for heat env artifact " + artifactInfo.getUniqueId() + ". Status is " + setRelevantHeatParamIdRes.right().value()); + return Either.right(setRelevantHeatParamIdRes.right().value()); + } + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, newArtifactUniqueId, id, artifactInfo.getArtifactLabel()); + if (updateResult.isRight()) { + log.error("Failed to update heat parameter " + heatEnvParam.getName() + ". Status is " + updateResult.right().value()); + return Either.right(updateResult.right().value()); + } + } + + Iterator<Edge> iterEdgeGeneratedFrom = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty()); + + if (!iterEdgeGeneratedFrom.hasNext()) { + log.error("No heat artifact node for id = " + artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Edge edgeToHeat = iterEdgeGeneratedFrom.next(); + Vertex vertexIn = edgeToHeat.inVertex(); + String generatedFromArtifactId = vertexIn.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef)); + UniqueIdData generatedFromArtifactNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, generatedFromArtifactId); + Either<GraphRelation, TitanOperationStatus> createRelationToGeneratedFromArtifactRes = titanGenericDao.createRelation(addedArtifact, generatedFromArtifactNode, GraphEdgeLabels.GENERATED_FROM, null); + if (createRelationToGeneratedFromArtifactRes.isRight()) { + log.error("Failed to create relation from heat_env " + addedArtifact.getUniqueId() + " to heat " + generatedFromArtifactNode); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationToGeneratedFromArtifactRes.right().value())); + } + } + } + return addedArtifactRes; + + } else { + if (edgeCount == 1) { + String oldChecksum = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_CHECKSUM.getProperty())); + String oldVersion = artifactV.valueOrNull(titanGenericDao.getGraph().left().value().getPropertyKey(GraphPropertiesDictionary.ARTIFACT_VERSION.getProperty())); + updateUUID(artifactInfo, oldChecksum, oldVersion); + // update exist + Either<ArtifactData, TitanOperationStatus> updatedArtifact = titanGenericDao.updateNode(artifactData, ArtifactData.class); + if (updatedArtifact.isRight()) { + log.debug("failed to update artifact node for id {}", artifactData.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updatedArtifact.right().value())); + } + + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + Either<HeatParameterValueData, StorageOperationStatus> updateResult = null; + String artifactUniqueId = artifactInfo.getUniqueId(); + setRelevantHeatParamIdRes = setRelevantHeatParamId(artifactV, artifactInfo); + if (setRelevantHeatParamIdRes.isRight()) { + log.error("Failed to set relevant id to heat parameters for heat env artifact {}. Status is {}", artifactInfo.getUniqueId(), setRelevantHeatParamIdRes.right().value()); + return Either.right(setRelevantHeatParamIdRes.right().value()); + } + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + updateResult = heatParametersOperation.updateHeatParameterValue(heatEnvParam, artifactUniqueId, id, artifactInfo.getArtifactLabel()); + if (updateResult.isRight()) { + log.error("Failed to update heat parameter " + heatEnvParam.getName() + ". Status is " + updateResult.right().value()); + return Either.right(updateResult.right().value()); + } + } + } else { + if (artifactData.getArtifactDataDefinition().getArtifactChecksum() == null) { + // update heat parameters only if it is not heat env + if (artifactInfo.getGeneratedFromId() == null) { + StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(artifactInfo.getHeatParameters()); + if (operationStatus != StorageOperationStatus.OK) { + return Either.right(operationStatus); + } + } + } else { + Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteParameters = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactInfo.getUniqueId()); + if (deleteParameters.isRight()) { + log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + StorageOperationStatus addParameters = heatParametersOperation.addPropertiesToGraph(artifactInfo.getHeatParameters(), artifactId, NodeTypeEnum.ArtifactRef); + if (!addParameters.equals(StorageOperationStatus.OK)) { + log.debug("failed to update heat parameters for artifact id {}", artifactData.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + } + + return Either.left(updatedArtifact.left().value()); + } else { + log.debug("No relevent edges for artifact = {}", artifactId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + } + + private Either<Boolean, StorageOperationStatus> setRelevantHeatParamId(TitanVertex artifactV, ArtifactDefinition artifactInfo) { + + Map<String, String> heatParametersHM = new HashMap<String, String>(); + + Iterator<Edge> iterHeat = artifactV.edges(Direction.OUT, GraphEdgeLabels.GENERATED_FROM.getProperty()); + if (!iterHeat.hasNext()) { + log.debug("No edges with label GENERATED_FROM for the node {}", artifactInfo.getUniqueId()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Edge heat = iterHeat.next(); + Vertex heatVertex = heat.inVertex(); + String heatUniqueId = (String) heatVertex.value(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef)); + + Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> getHeatParametersRes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatUniqueId, GraphEdgeLabels.HEAT_PARAMETER, + NodeTypeEnum.HeatParameter, HeatParameterData.class); + if (getHeatParametersRes.isRight()) { + log.debug("No heat parameters for heat artifact {}", heatUniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + List<ImmutablePair<HeatParameterData, GraphEdge>> heatParameters = getHeatParametersRes.left().value(); + if (heatParameters == null) { + log.debug("No heat parameters for heat artifact {}", heatUniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + for (ImmutablePair<HeatParameterData, GraphEdge> heatParamEdge : heatParameters) { + HeatParameterData heatParam = heatParamEdge.getLeft(); + heatParametersHM.put(heatParam.getName(), (String) heatParam.getUniqueId()); + } + String curName = null; + for (HeatParameterDefinition heatEnvParam : artifactInfo.getHeatParameters()) { + curName = heatEnvParam.getName(); + if (heatParametersHM.containsKey(curName)) { + heatEnvParam.setUniqueId(heatParametersHM.get(curName)); + } + } + return Either.left(true); + } + + public Either<Integer, StorageOperationStatus> getParentsOfArtifact(String artifactId, NodeTypeEnum type) { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Vertex artifactV = iterator.next(); + Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + int edgeCount = 0; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + ++edgeCount; + } + return Either.left(edgeCount); + } + + public Either<ArtifactData, TitanOperationStatus> removeArtifactOnGraph(String id, String artifactId, NodeTypeEnum type, String id2, boolean deleteMandatoryArtifact) { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + TitanGraph tGraph = graph.left().value(); + Either<ArtifactData, TitanOperationStatus> artifactData = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if (artifactData.isRight()) { + log.debug("Failed to retrieve artifact for id = {}", artifactId); + return Either.right(artifactData.right().value()); + } + ArtifactDataDefinition artifactDefinition = artifactData.left().value().getArtifactDataDefinition(); + boolean isMandatory = false; + if ((artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) && !deleteMandatoryArtifact) { + // return Either.left(artifactData.left().value()); + isMandatory = true; + } + + @SuppressWarnings("unchecked") + Iterable<TitanVertex> verticesArtifact = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No artifact node for id = {}", artifactId); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + Vertex artifactV = iterator.next(); + Iterator<Edge> iterEdge = artifactV.edges(Direction.IN, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + int edgeCount = 0; + Edge edgeFromTo = null; + while (iterEdge.hasNext()) { + Edge edge = iterEdge.next(); + Vertex vertexFrom = edge.outVertex(); + String vertexId = vertexFrom.value(UniqueIdBuilder.getKeyByNodeType(type)); + if (id.equals(vertexId)) { + edgeFromTo = edge; + } + ++edgeCount; + } + if (edgeFromTo == null) { + log.debug("No relation between artifact = {} and node with id = {}", artifactId, id); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + + // need to remove relation from resource/interface + + log.debug("remove edge {}", edgeFromTo); + if (!isMandatory || (isMandatory && edgeCount > 1)) { + edgeFromTo.remove(); + } + + // delete edges from all groups under the component id which related to + // this artifact. + // Also in case it is a mandatory artifact. + Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroups = groupOperation.dissociateAllGroupsFromArtifactOnGraph(id, type, artifactId); + if (dissociateAllGroups.isRight()) { + TitanOperationStatus status = dissociateAllGroups.right().value(); + if (status != TitanOperationStatus.NOT_FOUND && status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + + if (edgeCount == 1) { + // remove artifactRef node + log.debug("Remove artifactRef node from graph"); + Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteStatus = heatParametersOperation.deleteAllHeatParametersAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId); + if (deleteStatus.isRight()) { + log.error("failed to delete heat parameters of artifact " + artifactId); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + + StorageOperationStatus deleteValuesStatus = heatParametersOperation.deleteAllHeatValuesAssociatedToNode(NodeTypeEnum.ArtifactRef, artifactId); + if (!deleteValuesStatus.equals(StorageOperationStatus.OK)) { + log.error("failed to delete heat values of artifact " + artifactId); + return Either.right(TitanOperationStatus.GENERAL_ERROR); + } + if (!isMandatory) { + artifactV.remove(); + } + } else { + log.debug("artifactRef have more connection. ArtifactRef node will not be removed "); + } + + return Either.left(artifactData.left().value()); + + } + + /** + * + * @param parentId + * @param parentType + * @param inTransaction + * @return + */ + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction) { + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = null; + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + Iterator<TitanVertex> iterator = vertices.iterator(); + + Map<String, ArtifactDefinition> artifactMap = new HashMap<String, ArtifactDefinition>(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + Iterator<Edge> iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + if (iteratorEdge != null) { + + while (iteratorEdge.hasNext()) { + Edge edge = iteratorEdge.next(); + + Vertex artifactV = edge.inVertex(); + + Map<String, Object> properties = this.titanGenericDao.getProperties(artifactV); + ArtifactData artifact = GraphElementFactory.createElement(NodeTypeEnum.ArtifactRef.getName(), GraphElementTypeEnum.Node, properties, ArtifactData.class); + if (artifact != null) { + + ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifact.getArtifactDataDefinition()); + List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {} {}", parentType.getName(), parentId); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDefinition.setHeatParameters(heatParams); + } + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + log.debug("Artifact was added to list {}", artifact.getUniqueId()); + } + } + } + } + result = Either.left(artifactMap); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + + } + + public Either<Map<String, TitanVertex>, StorageOperationStatus> getArtifactsVertecies(String parentId, NodeTypeEnum parentType, boolean inTransaction) { + Either<Map<String, TitanVertex>, StorageOperationStatus> result = null; + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + Iterator<TitanVertex> iterator = vertices.iterator(); + + Map<String, TitanVertex> artifactMap = new HashMap<String, TitanVertex>(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + Iterator<Edge> iteratorEdge = vertex.edges(Direction.OUT, GraphEdgeLabels.ARTIFACT_REF.getProperty()); + + if (iteratorEdge != null) { + + while (iteratorEdge.hasNext()) { + Edge edge = iteratorEdge.next(); + + TitanVertex artifactV = (TitanVertex) edge.inVertex(); + String label = (String) titanGenericDao.getProperty(artifactV, GraphPropertiesDictionary.ARTIFACT_LABEL.getProperty()); + artifactMap.put(label, artifactV); + log.debug("Artifact was added to list {}", label); + } + } + } + result = Either.left(artifactMap); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> getArtifactById(String id, boolean inTransaction) { + Either<ArtifactDefinition, StorageOperationStatus> result = null; + try { + Either<ArtifactData, TitanOperationStatus> artifact = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), id, ArtifactData.class); + if (artifact.isRight()) { + if (artifact.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.right(StorageOperationStatus.ARTIFACT_NOT_FOUND); + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(artifact.right().value())); + } + return result; + } + ArtifactData artifactData = artifact.left().value(); + + ArtifactDefinition artifactDef = new ArtifactDefinition(artifactData.getArtifactDataDefinition()); + List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDef.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for artifact {}", id); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDef.setHeatParameters(heatParams); + } + + Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> generatedFromArtifact = titanGenericDao.getChild(artifactData.getUniqueIdKey(), (String) artifactData.getUniqueId(), GraphEdgeLabels.GENERATED_FROM, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + if (generatedFromArtifact.isLeft()) { + ImmutablePair<ArtifactData, GraphEdge> pair = generatedFromArtifact.left().value(); + String generatedFromId = (String) pair.left.getUniqueId(); + log.debug("artifact {} is generated from {}.", artifactData.getUniqueId(), generatedFromId); + artifactDef.setGeneratedFromId(generatedFromId); + Either<List<HeatParameterDefinition>, StorageOperationStatus> heatParamsForEnv = getHeatParamsForEnv(artifactDef); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", artifactDef.getUniqueId()); + return Either.right(heatParamsForEnv.right().value()); + } else { + artifactDef.setHeatParameters(heatParamsForEnv.left().value()); + } + } + + result = Either.left(artifactDef); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + public Either<List<HeatParameterDefinition>, StorageOperationStatus> getHeatParamsForEnv(ArtifactDefinition heatEnvArtifact) { + + List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, heatEnvArtifact.getGeneratedFromId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {}", heatEnvArtifact.getGeneratedFromId()); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + + Map<String, HeatParameterValueData> heatValuesMap = new HashMap<String, HeatParameterValueData>(); + Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, TitanOperationStatus> heatEnvValuesWithEdges = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), heatEnvArtifact.getUniqueId(), + GraphEdgeLabels.PARAMETER_VALUE, NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class); + + if (heatEnvValuesWithEdges.isRight() && !heatEnvValuesWithEdges.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = heatEnvValuesWithEdges.right().value(); + if (!status.equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else if (heatEnvValuesWithEdges.isLeft()) { + for (ImmutablePair<HeatParameterValueData, GraphEdge> pair : heatEnvValuesWithEdges.left().value()) { + HeatParameterValueData parameterValue = pair.left; + Object heatParameterName = pair.right.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + heatValuesMap.put((String) heatParameterName, parameterValue); + } + } + + for (HeatParameterDefinition parameter : heatParams) { + if (parameter.getCurrentValue() != null) { + if ("number".equals(parameter.getType())) { + parameter.setDefaultValue(new BigDecimal(parameter.getCurrentValue()).toPlainString()); + } else { + parameter.setDefaultValue(parameter.getCurrentValue()); + } + } + HeatParameterValueData heatParameterValueData = heatValuesMap.get(parameter.getName()); + if (heatParameterValueData != null && heatParameterValueData.getValue() != null) { + if ("number".equals(parameter.getType())) { + parameter.setCurrentValue(new BigDecimal(heatParameterValueData.getValue()).toPlainString()); + } else { + parameter.setCurrentValue(heatParameterValueData.getValue()); + } + parameter.setUniqueId((String) heatParameterValueData.getUniqueId()); + + } + } + } + + return Either.left(heatParams); + + } + + @Override + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, String groupType) { + + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = null; + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentType), parentId).vertices(); + if (vertices == null || vertices.iterator() == null || false == vertices.iterator().hasNext()) { + log.debug("No nodes for type {} for id = {}", parentType, parentId); + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + + Iterator<TitanVertex> iterator = vertices.iterator(); + Vertex vertex = iterator.next(); + + Map<String, Object> edgeProperties = null; + if (groupType != null) { + edgeProperties = new HashMap<>(); + edgeProperties.put(GraphEdgePropertiesDictionary.GROUP_TYPE.getProperty(), groupType); + } + Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, parentId, GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class, + edgeProperties); + + if (childrenByEdgeCriteria.isRight()) { + TitanOperationStatus status = childrenByEdgeCriteria.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenByEdgeCriteria.left().value(); + + Map<String, ArtifactDefinition> artifactsMap = new HashMap<>(); + + for (ImmutablePair<ArtifactData, GraphEdge> pair : list) { + ArtifactData artifactData = pair.getLeft(); + ArtifactDefinition artifactDefinition = new ArtifactDefinition(artifactData.getArtifactDataDefinition()); + + List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus heatParametersStatus = heatParametersOperation.getHeatParametersOfNode(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId(), heatParams); + if (!heatParametersStatus.equals(StorageOperationStatus.OK)) { + log.debug("failed to get heat parameters for node {} {}", parentType.getName(), parentId); + return Either.right(heatParametersStatus); + } + if (!heatParams.isEmpty()) { + artifactDefinition.setHeatParameters(heatParams); + } + + Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> getResult = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactDefinition.getUniqueId(), GraphEdgeLabels.GENERATED_FROM, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + + if (getResult.isRight()) { + TitanOperationStatus status = getResult.right().value(); + if (!status.equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else { + ImmutablePair<ArtifactData, GraphEdge> immutablePair = getResult.left().value(); + artifactDefinition.setGeneratedFromId((String) immutablePair.left.getUniqueId()); + } + + artifactsMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + log.debug("Artifact {} was added to list ", artifactData.getUniqueId()); + } + + result = Either.left(artifactsMap); + return result; + + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifactHeat, String parentId, NodeTypeEnum parentType, boolean inTransaction) { + + Either<ArtifactDefinition, StorageOperationStatus> result = null; + try { + Either<ArtifactDefinition, StorageOperationStatus> heatArtifactOnGraph = addArifactToComponent(artifactHeatEnv, parentId, parentType, true, true); + + if (heatArtifactOnGraph.isRight()) { + log.debug("failed to create heat env artifact on graph"); + result = heatArtifactOnGraph; + return result; + } + + ArtifactDefinition artifactDefinition = heatArtifactOnGraph.left().value(); + + // add relation from heatEnv to heat + UniqueIdData heatData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactHeat.getUniqueId()); + UniqueIdData heatEnvData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactDefinition.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(heatEnvData, heatData, GraphEdgeLabels.GENERATED_FROM, null); + + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + log.debug("failed to add relation from heat_env artifact to heat artifact. error: {}", status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + artifactDefinition.setGeneratedFromId(artifactHeat.getUniqueId()); + log.trace("heat env artifact added successfuly to resource instance"); + result = Either.left(artifactDefinition); + return result; + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + public void updateUUID(ArtifactDataDefinition artifactData, String oldChecksum, String oldVesrion) { + if (oldVesrion == null || oldVesrion.isEmpty()) + oldVesrion = "0"; + + String currentChecksum = artifactData.getArtifactChecksum(); + if (oldChecksum == null || oldChecksum.isEmpty()) { + if (currentChecksum != null) { + generateUUID(artifactData, oldVesrion); + } + } else if ((currentChecksum != null && !currentChecksum.isEmpty()) && !oldChecksum.equals(currentChecksum)) { + generateUUID(artifactData, oldVesrion); + } + + } + + private void generateUUID(ArtifactDataDefinition artifactData, String oldVesrion) { + + UUID uuid = UUID.randomUUID(); + artifactData.setArtifactUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + long time = System.currentTimeMillis(); + artifactData.setPayloadUpdateDate(time); + int newVersion = new Integer(oldVesrion).intValue(); + newVersion++; + artifactData.setArtifactVersion(String.valueOf(newVersion)); + } + + @Override + public Either<ArtifactDefinition, StorageOperationStatus> getHeatArtifactByHeatEnvId(String heatEnvId, boolean inTransaction) { + + Either<ArtifactDefinition, StorageOperationStatus> result = null; + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Failed to work with graph {}", graph.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + } + TitanGraph tGraph = graph.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = tGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), heatEnvId).vertices(); + if (vertices == null || vertices.iterator() == null || false == vertices.iterator().hasNext()) { + log.debug("No nodes for type {} for id = {}", NodeTypeEnum.ArtifactRef, heatEnvId); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Iterator<TitanVertex> iterator = vertices.iterator(); + Vertex vertex = iterator.next(); + + Map<String, Object> edgeProperties = null; + Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenByEdgeCriteria = titanGenericDao.getChildrenByEdgeCriteria(vertex, heatEnvId, GraphEdgeLabels.GENERATED_FROM, NodeTypeEnum.ArtifactRef, ArtifactData.class, + edgeProperties); + + if (childrenByEdgeCriteria.isRight()) { + TitanOperationStatus status = childrenByEdgeCriteria.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenByEdgeCriteria.left().value(); + + if (list == null || list.isEmpty() == true) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + if (list.size() > 1) { + return Either.right(StorageOperationStatus.INVALID_ID); + } + + ImmutablePair<ArtifactData, GraphEdge> immutablePair = list.get(0); + + ArtifactDefinition artifactDefinition = new ArtifactDefinition(immutablePair.left.getArtifactDataDefinition()); + + log.debug("The artifact {} was generated from artifact {}", heatEnvId, artifactDefinition); + + result = Either.left(artifactDefinition); + return result; + + } finally { + if (inTransaction == false) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + + } + } + } + + @Override + public Either<ArtifactData, StorageOperationStatus> getLatestArtifactDataByArtifactUUID(String artifactUUID, boolean inTransaction) { + Either<ArtifactData, StorageOperationStatus> result = null; + try { + NodeTypeEnum nodeType = NodeTypeEnum.ArtifactRef; + Map<String, Object> propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.ARTIFACT_UUID.getProperty(), artifactUUID); + Either<List<ArtifactData>, TitanOperationStatus> getArtifactEither = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, ArtifactData.class); + if (getArtifactEither.isRight()) { + log.debug("Couldn't fetch artifact data for artifact with uuid {}, error: {}", nodeType, getArtifactEither.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getArtifactEither.right().value())); + } else { + List<ArtifactData> artifacts = getArtifactEither.left().value(); + ArtifactData latestArtifact = artifacts.size() == 1 ? artifacts.get(0) + : artifacts.stream().max((a1, a2) -> Double.compare(Double.parseDouble(a1.getArtifactDataDefinition().getArtifactVersion()), Double.parseDouble(a2.getArtifactDataDefinition().getArtifactVersion()))).get(); + result = Either.left(latestArtifact); + } + return result; + } finally { + if (!inTransaction) { + if (result == null || result.isRight()) { + this.titanGenericDao.rollback(); + } else { + this.titanGenericDao.commit(); + } + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java new file mode 100644 index 0000000000..fc81a9affd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java @@ -0,0 +1,463 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.AttributeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * Class For Data Model Logic Relevant For Attributes + * + * @author mshitrit + * + */ +@Component("attribute-operation") +public class AttributeOperation extends AbstractOperation implements IAttributeOperation { + private static Logger log = LoggerFactory.getLogger(AttributeOperation.class.getName()); + @Autowired + private IPropertyOperation propertyOperation; + + /** + * + * Add attribute to graph. + * + * 1. Add attribute node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per property & if exists) + * + * @param attributeDefinition + * @return + */ + private Either<AttributeData, TitanOperationStatus> addAttributeToNodeType(AttributeDefinition attributeDefinition, NodeTypeEnum nodeType, String nodeUniqueId) { + String attUniqueId = UniqueIdBuilder.buildAttributeUid(nodeUniqueId, attributeDefinition.getName()); + Supplier<AttributeData> dataBuilder = () -> buildAttributeData(attributeDefinition, attUniqueId); + Supplier<String> defNameGenerator = () -> "Attribute : " + attributeDefinition.getName(); + + return addDefinitionToNodeType(attributeDefinition, nodeType, nodeUniqueId, GraphEdgeLabels.ATTRIBUTE, dataBuilder, defNameGenerator); + + } + + private TitanOperationStatus addAttributeToNodeType(TitanVertex metadataVertex, AttributeDefinition attributeDefinition, NodeTypeEnum nodeType, String nodeUniqueId) { + String attUniqueId = UniqueIdBuilder.buildAttributeUid(nodeUniqueId, attributeDefinition.getName()); + Supplier<AttributeData> dataBuilder = () -> buildAttributeData(attributeDefinition, attUniqueId); + Supplier<String> defNameGenerator = () -> "Attribute : " + attributeDefinition.getName(); + + return addDefinitionToNodeType(metadataVertex, attributeDefinition, nodeType, nodeUniqueId, GraphEdgeLabels.ATTRIBUTE, dataBuilder, defNameGenerator); + + } + + private AttributeData buildAttributeData(AttributeDefinition attributeDefinition, String attUniqueId) { + attributeDefinition.setUniqueId(attUniqueId); + return new AttributeData(attributeDefinition); + } + + @Override + public Either<AttributeData, StorageOperationStatus> deleteAttribute(String attributeId) { + Either<AttributeData, TitanOperationStatus> either = deleteAttributeFromGraph(attributeId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + @Override + public Either<Map<String, AttributeDefinition>, StorageOperationStatus> deleteAllAttributeAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + Wrapper<TitanOperationStatus> errorWrapper; + List<AttributeDefinition> attributes = new ArrayList<>(); + TitanOperationStatus findAllResourceAttribues = findNodeNonInheretedAttribues(uniqueId, NodeTypeEnum.Resource, attributes); + errorWrapper = (findAllResourceAttribues != TitanOperationStatus.OK) ? new Wrapper<>(findAllResourceAttribues) : new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + for (AttributeDefinition attDef : attributes) { + log.debug("Before deleting attribute from graph {}", attDef.getUniqueId()); + Either<AttributeData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attDef.getUniqueId(), AttributeData.class); + if (deleteNode.isRight()) { + errorWrapper.setInnerElement(deleteNode.right().value()); + break; + } + } + } + + if (errorWrapper.isEmpty()) { + Map<String, AttributeDefinition> attributesMap = attributes.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + return Either.left(attributesMap); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(errorWrapper.getInnerElement())); + } + + } + + private Either<AttributeData, TitanOperationStatus> deleteAttributeFromGraph(String attributeId) { + log.debug("Before deleting attribute from graph {}", attributeId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attributeId, AttributeData.class); + } + + @Override + public TitanOperationStatus addAttributesToGraph(TitanVertex metadataVertex, Map<String, AttributeDefinition> attributes, String resourceId, Map<String, DataTypeDefinition> dataTypes) { + TitanOperationStatus titanStatus = TitanOperationStatus.OK; + for (AttributeDefinition attribute : attributes.values()) { + TitanOperationStatus eitherAddAttribute = addAttributeToGraphByVertex(metadataVertex, attribute, resourceId, dataTypes); + if (!eitherAddAttribute.equals(TitanOperationStatus.OK)) { + titanStatus = eitherAddAttribute; + break; + } + } + return titanStatus; + } + + @Override + public Either<List<ComponentInstanceAttribute>, TitanOperationStatus> getAllAttributesOfResourceInstance(ComponentInstance compInstance) { + + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> result; + + Either<List<ImmutablePair<AttributeValueData, GraphEdge>>, TitanOperationStatus> attributeImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), compInstance.getUniqueId(), + GraphEdgeLabels.ATTRIBUTE_VALUE, NodeTypeEnum.AttributeValue, AttributeValueData.class); + + // Build From Resource + if (attributeImplNodes.isRight() && attributeImplNodes.right().value() == TitanOperationStatus.NOT_FOUND) { + result = getAttributesFromResource(compInstance); + } + // Build From Instance + else if (attributeImplNodes.isLeft()) { + List<ImmutablePair<AttributeValueData, GraphEdge>> attributesFromRI = attributeImplNodes.left().value(); + result = mergeAttributesResults(getAttributesFromResource(compInstance), convertToComponentInstanceAttribute(attributesFromRI)); + } + // Error + else { + TitanOperationStatus status = attributeImplNodes.right().value(); + result = Either.right(status); + } + + return result; + } + + private Either<List<ComponentInstanceAttribute>, TitanOperationStatus> mergeAttributesResults(Either<List<ComponentInstanceAttribute>, TitanOperationStatus> eitherAttributesThatDoesNotExistOnRI, + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> eitherAttributesThatExistOnRI) { + + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> result; + if (eitherAttributesThatExistOnRI.isRight()) { + result = Either.right(eitherAttributesThatExistOnRI.right().value()); + } else if (eitherAttributesThatDoesNotExistOnRI.isRight()) { + result = Either.right(eitherAttributesThatDoesNotExistOnRI.right().value()); + } else { + final List<ComponentInstanceAttribute> attributesThatExistOnRI = eitherAttributesThatExistOnRI.left().value(); + final List<ComponentInstanceAttribute> attributesThatDoesNotExistOnRI = eitherAttributesThatDoesNotExistOnRI.left().value(); + Set<String> attributesIdThatExistOnRI = attributesThatExistOnRI.stream().map(e -> e.getUniqueId()).collect(Collectors.toSet()); + // Attributes From The Resource Without attributes that also exist + // on the instance + Stream<ComponentInstanceAttribute> filterAttributesThatDoesNotExistOnRI = attributesThatDoesNotExistOnRI.stream().filter(e -> !attributesIdThatExistOnRI.contains(e.getUniqueId())); + // Add Fields From Resource Attributes + fillAttributeInfoFromResource(attributesThatExistOnRI, attributesThatDoesNotExistOnRI); + // Adding the Attributes on the instance for the full list + List<ComponentInstanceAttribute> mergedList = Stream.concat(filterAttributesThatDoesNotExistOnRI, attributesThatExistOnRI.stream()).collect(Collectors.toList()); + result = Either.left(mergedList); + } + return result; + } + + private void fillAttributeInfoFromResource(List<ComponentInstanceAttribute> attributesThatExistOnRI, List<ComponentInstanceAttribute> attributesThatDoesNotExistOnRI) { + attributesThatExistOnRI.stream() + .forEach(e -> addAttributeInfo(e, + // Finds the same attribute in the resource + attributesThatDoesNotExistOnRI.stream().filter(e2 -> e2.getUniqueId().equals(e.getUniqueId())).findAny().get())); + + } + + private void addAttributeInfo(ComponentInstanceAttribute attributeFromRI, ComponentInstanceAttribute attributeFromResource) { + attributeFromRI.setName(attributeFromResource.getName()); + attributeFromRI.setDescription(attributeFromResource.getDescription()); + attributeFromRI.setDefaultValue(attributeFromResource.getDefaultValue()); + attributeFromRI.setStatus(attributeFromResource.getStatus()); + attributeFromRI.setSchema(attributeFromResource.getSchema()); + if (StringUtils.isEmpty(attributeFromRI.getValue())) { + attributeFromRI.setValue(attributeFromResource.getDefaultValue()); + } + } + + private Either<List<ComponentInstanceAttribute>, TitanOperationStatus> getAttributesFromResource(ComponentInstance compInstance) { + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> result; + List<AttributeDefinition> attributes = new ArrayList<>(); + // Attributes does not exist on Ri - fetch them from resource + TitanOperationStatus findAllResourceAttribues = findAllResourceAttributesRecursively(compInstance.getComponentUid(), attributes); + if (findAllResourceAttribues != TitanOperationStatus.OK) { + result = Either.right(findAllResourceAttribues); + } else { + List<ComponentInstanceAttribute> buildAttInstanceFromResource = attributes.stream().map(attDef -> new ComponentInstanceAttribute(attDef, false, null)).collect(Collectors.toList()); + + // Set Value to be default value in case it is empty + Consumer<ComponentInstanceAttribute> valueSetter = data -> { + if (StringUtils.isEmpty(data.getValue())) { + data.setValue(data.getDefaultValue()); + } + }; + buildAttInstanceFromResource.stream().forEach(valueSetter); + + result = Either.left(buildAttInstanceFromResource); + } + return result; + } + + private Either<List<ComponentInstanceAttribute>, TitanOperationStatus> convertToComponentInstanceAttribute(List<ImmutablePair<AttributeValueData, GraphEdge>> list) { + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> result = null; + List<ComponentInstanceAttribute> componentInstanceAttribute = new ArrayList<>(); + for (ImmutablePair<AttributeValueData, GraphEdge> attributeValue : list) { + AttributeValueData attributeValueData = attributeValue.getLeft(); + String attributeValueUid = attributeValueData.getUniqueId(); + + Either<ImmutablePair<AttributeData, GraphEdge>, TitanOperationStatus> attributeDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.AttributeValue), attributeValueUid, GraphEdgeLabels.ATTRIBUTE_IMPL, + NodeTypeEnum.Attribute, AttributeData.class); + + if (attributeDefRes.isRight()) { + TitanOperationStatus status = attributeDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + result = Either.right(status); + break; + } else { + ImmutablePair<AttributeData, GraphEdge> attributeDefPair = attributeDefRes.left().value(); + String attributeUniqueId = attributeDefPair.left.getUniqueId(); + + ComponentInstanceAttribute resourceInstanceAttribute = new ComponentInstanceAttribute(); + // set attribute original unique id + resourceInstanceAttribute.setUniqueId(attributeUniqueId); + // set hidden + resourceInstanceAttribute.setHidden(attributeValueData.isHidden()); + // set value + resourceInstanceAttribute.setValue(attributeValueData.getValue()); + // set property value unique id + resourceInstanceAttribute.setValueUniqueUid(attributeValueUid); + + resourceInstanceAttribute.setType(attributeValueData.getType()); + + componentInstanceAttribute.add(resourceInstanceAttribute); + } + + } + if (result == null) { + result = Either.left(componentInstanceAttribute); + } + return result; + } + + /** + * fetch all attributes under a given resource(includes its parents' resources) + * + * @param resourceId + * @param attributes + * @return + */ + @Override + public TitanOperationStatus findAllResourceAttributesRecursively(String resourceId, List<AttributeDefinition> attributes) { + final NodeElementFetcher<AttributeDefinition> singleNodeFetcher = (resourceIdParam, attributesParam) -> findNodeNonInheretedAttribues(resourceIdParam, NodeTypeEnum.Resource, attributesParam); + return findAllResourceElementsDefinitionRecursively(resourceId, attributes, singleNodeFetcher); + + } + + @Override + public TitanOperationStatus findNodeNonInheretedAttribues(String uniqueId, NodeTypeEnum nodeType, List<AttributeDefinition> attributes) { + Either<List<ImmutablePair<AttributeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.ATTRIBUTE, NodeTypeEnum.Attribute, + AttributeData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List<ImmutablePair<AttributeData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<AttributeData, GraphEdge> immutablePair : values) { + AttributeData attData = immutablePair.getLeft(); + String attributeName = attData.getAttributeDataDefinition().getName(); + + log.debug("Attribute {} is associated to node {}", attributeName, uniqueId); + AttributeData attributeData = immutablePair.getKey(); + AttributeDefinition attributeDefinition = this.convertAttributeDataToAttributeDefinition(attributeData, attributeName, uniqueId); + + attributes.add(attributeDefinition); + + log.trace("findAttributesOfNode - property {} associated to node {}", attributeDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + @Override + public AttributeDefinition convertAttributeDataToAttributeDefinition(AttributeData attributeData, String attributeName, String resourceId) { + log.debug("The object returned after create attribute is {}", attributeData); + AttributeDefinition attributeDefResult = new AttributeDefinition(attributeData.getAttributeDataDefinition()); + attributeDefResult.setName(attributeName); + attributeDefResult.setParentUniqueId(resourceId); + return attributeDefResult; + } + + @Override + public Either<AttributeData, StorageOperationStatus> addAttribute(AttributeDefinition attributeDefinition, String resourceId) { + + Either<AttributeData, StorageOperationStatus> eitherResult; + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + eitherResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + Either<AttributeData, TitanOperationStatus> either = addAttributeToGraph(attributeDefinition, resourceId, allDataTypes.left().value()); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + eitherResult = Either.right(storageStatus); + } else { + eitherResult = Either.left(either.left().value()); + } + } + return eitherResult; + } + + @Override + public Either<AttributeData, StorageOperationStatus> updateAttribute(String attributeId, AttributeDefinition newAttDef, Map<String, DataTypeDefinition> dataTypes) { + + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(newAttDef, dataTypes); + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + return Either.right(validateAndUpdateAttribute); + } + + Either<AttributeData, TitanOperationStatus> either = updateAttributeFromGraph(attributeId, newAttDef); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + private Either<AttributeData, TitanOperationStatus> updateAttributeFromGraph(String attributeId, AttributeDefinition attributeDefenition) { + log.debug("Before updating attribute on graph {}", attributeId); + + // get the original property data + Either<AttributeData, TitanOperationStatus> eitherAttribute = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Attribute), attributeId, AttributeData.class); + if (eitherAttribute.isRight()) { + log.debug("Problem while get Attribute with id {}. Reason - {}", attributeId, eitherAttribute.right().value().name()); + return Either.right(eitherAttribute.right().value()); + } + AttributeData orgAttributeData = eitherAttribute.left().value(); + AttributeDataDefinition orgAttributeDataDefinition = orgAttributeData.getAttributeDataDefinition(); + + // create new property data to update + AttributeData newAttributeData = new AttributeData(); + newAttributeData.setAttributeDataDefinition(attributeDefenition); + AttributeDataDefinition newAttributeDataDefinition = newAttributeData.getAttributeDataDefinition(); + + // update the original property data with new values + if (!Objects.equals(orgAttributeDataDefinition.getDefaultValue(), newAttributeDataDefinition.getDefaultValue())) { + orgAttributeDataDefinition.setDefaultValue(newAttributeDataDefinition.getDefaultValue()); + } + + if (!Objects.equals(orgAttributeDataDefinition.getDescription(), newAttributeDataDefinition.getDescription())) { + orgAttributeDataDefinition.setDescription(newAttributeDataDefinition.getDescription()); + } + + if (!Objects.equals(orgAttributeDataDefinition.getType(), newAttributeDataDefinition.getType())) { + orgAttributeDataDefinition.setType(newAttributeDataDefinition.getType()); + } + + orgAttributeDataDefinition.setSchema(newAttributeDataDefinition.getSchema()); + + return titanGenericDao.updateNode(orgAttributeData, AttributeData.class); + } + + @Override + public ComponentInstanceAttribute buildResourceInstanceAttribute(AttributeValueData attributeValueData, ComponentInstanceAttribute resourceInstanceAttribute) { + + Boolean hidden = attributeValueData.isHidden(); + String uid = attributeValueData.getUniqueId(); + ComponentInstanceAttribute instanceAttribute = new ComponentInstanceAttribute(resourceInstanceAttribute, hidden, uid); + + return instanceAttribute; + } + + @Override + public Either<AttributeData, TitanOperationStatus> addAttributeToGraph(AttributeDefinition attribute, String resourceId, Map<String, DataTypeDefinition> dataTypes) { + Either<AttributeData, TitanOperationStatus> eitherResult; + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(attribute, dataTypes); + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + log.error("Attribute " + attribute + " is invalid. Status is " + validateAndUpdateAttribute); + eitherResult = Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } else { + eitherResult = addAttributeToNodeType(attribute, NodeTypeEnum.Resource, resourceId); + + } + return eitherResult; + } + + @Override + public TitanOperationStatus addAttributeToGraphByVertex(TitanVertex metadataVertex, AttributeDefinition attribute, String resourceId, Map<String, DataTypeDefinition> dataTypes) { + StorageOperationStatus validateAndUpdateAttribute = propertyOperation.validateAndUpdateProperty(attribute, dataTypes); + TitanOperationStatus result; + if (validateAndUpdateAttribute != StorageOperationStatus.OK) { + log.error("Attribute {} is invalid. Status is {}", attribute, validateAndUpdateAttribute); + result = TitanOperationStatus.ILLEGAL_ARGUMENT; + } else { + result = addAttributeToNodeType(metadataVertex, attribute, NodeTypeEnum.Resource, resourceId); + + } + return result; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java new file mode 100644 index 0000000000..d05255473d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java @@ -0,0 +1,213 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.cache.*; +import org.openecomp.sdc.be.model.cache.jobs.*; +import org.openecomp.sdc.be.model.cache.workers.CacheWorker; +import org.openecomp.sdc.be.model.cache.workers.IWorker; +import org.openecomp.sdc.be.model.cache.workers.SyncWorker; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.workers.Manager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import java.util.LinkedList; +import java.util.concurrent.*; + +/** + * Created by mlando on 9/5/2016. the class is responsible for handling all + * cache update operations asynchronously including sync between the graph and + * cache and on demand update requests + */ +@Component("cacheManger-operation") +public class CacheMangerOperation implements ICacheMangerOperation { + @Autowired + private IResourceOperation iResourceOperation; + @Autowired + private IServiceOperation iServiceOperation; + @Autowired + private IProductOperation iProductOperation; + @Autowired + private TitanGenericDao titanGenericDao; + @Autowired + private ComponentCache componentCache; + + private static Logger log = LoggerFactory.getLogger(Manager.class.getName()); + private LinkedBlockingQueue<Job> jobQueue = null; + private int waitOnShutDownInMinutes; + private ScheduledExecutorService syncExecutor; + private ExecutorService workerExecutor; + private LinkedList<IWorker> workerList = new LinkedList<>(); + private DaoInfo daoInfo; + + /** + * constructor + */ + public CacheMangerOperation() { + // daoInfo = new DaoInfo(iResourceOperation, iServiceOperation, + // iProductOperation, componentCache); + } + + /** + * the method checks in the cache is enabled, if it is, it initializes all + * the workers according to the configuration values. + */ + @PostConstruct + public void init() { + + daoInfo = new DaoInfo(iResourceOperation, iServiceOperation, iProductOperation, componentCache); + + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + Integer numberOfWorkers = applicationL2CacheConfig.getQueue().getNumberOfCacheWorkers(); + this.waitOnShutDownInMinutes = applicationL2CacheConfig.getQueue().getWaitOnShutDownInMinutes(); + jobQueue = new LinkedBlockingQueue<>(); + log.info("L2 Cache is enabled inishilsing queue"); + log.debug("initializing SyncWorker, creating {} workers"); + ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("Sync-Cache-Worker-%d").build(); + this.syncExecutor = Executors.newSingleThreadScheduledExecutor(threadFactory); + log.debug("initializing workers, creating {} cacheWorkers", numberOfWorkers); + threadFactory = new ThreadFactoryBuilder().setNameFormat("Cache-Worker-%d").build(); + String workerName = "Sync-Worker"; + Integer syncWorkerExacutionIntrval = applicationL2CacheConfig.getQueue().getSyncIntervalInSecondes(); + log.debug("starting Sync worker:{} with executions interval:{} ", workerName, syncWorkerExacutionIntrval); + SyncWorker syncWorker = new SyncWorker(workerName, this); + this.syncExecutor.scheduleAtFixedRate(syncWorker, 5 * 60, syncWorkerExacutionIntrval, TimeUnit.SECONDS); + this.workerExecutor = Executors.newFixedThreadPool(numberOfWorkers, threadFactory); + CacheWorker cacheWorker; + for (int i = 0; i < numberOfWorkers; i++) { + workerName = "Cache-Worker-" + i; + log.debug("starting Cache worker:{}", workerName); + cacheWorker = new CacheWorker(workerName, jobQueue); + this.workerExecutor.submit(cacheWorker); + this.workerList.add(cacheWorker); + } + } else { + log.info("L2 Cache is disabled"); + } + log.info("L2 Cache has been initialized and the workers are running"); + } + + /** + * the method creates a job to check it the given component is in the cach + * and if so is it valid if the value in the cache is not valid it will be + * updated. + * + * @param componentId + * the uid of the component we want to update + * @param timestamp + * the time of the component update + * @param nodeTypeEnum + * the type of the component resource/service/product + */ + @Override + public void updateComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new CheckAndUpdateJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + public void overideComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new OverrideJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + public void deleteComponentInCache(String componentId, long timestamp, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new DeleteJob(daoInfo, componentId, nodeTypeEnum, timestamp)); + } + } + + /** + * the method stores the given component in the cache + * + * @param component + * componet to store in cache + * @param nodeTypeEnum + * the type of the component we want to store + */ + @Override + public void storeComponentInCache(org.openecomp.sdc.be.model.Component component, NodeTypeEnum nodeTypeEnum) { + Configuration.ApplicationL2CacheConfig applicationL2CacheConfig = ConfigurationManager.getConfigurationManager() + .getConfiguration().getApplicationL2Cache(); + if (applicationL2CacheConfig != null && applicationL2CacheConfig.isEnabled()) { + this.jobQueue.add(new StoreJob(daoInfo, component, nodeTypeEnum)); + } + } + + /** + * the method shutdown's all the worker's. the method has a pre set of how + * long it will wait for the workers to shutdown. the pre defined value is + * taken from the configuration. + */ + @PreDestroy + public void shutDown() { + workerExecutor.shutdown(); + syncExecutor.shutdown(); + this.workerList.forEach(e -> e.shutDown()); + try { + if (!workerExecutor.awaitTermination(this.waitOnShutDownInMinutes, TimeUnit.MINUTES)) { + log.error("timer elapsed while waiting for Cache workers to finish, forcing a shutdown. "); + } + log.debug("all Cache workers finished"); + } catch (InterruptedException e) { + log.error("failed while waiting for Cache worker", e); + } + try { + if (!workerExecutor.awaitTermination(1, TimeUnit.MINUTES)) { + log.error("timer elapsed while waiting for the Sync worker's to finish, forcing a shutdown. "); + } + log.debug("sync worker finished"); + } catch (InterruptedException e) { + log.error("failed while waiting for sync worker", e); + } + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public ComponentCache getComponentCache() { + return componentCache; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java new file mode 100644 index 0000000000..0c4f35fd54 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java @@ -0,0 +1,1215 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.ICapabilityInstanceOperation; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * public class CapabilityInstanceOperation provides methods for CRUD operations for CapabilityInstance on component instance level + * + * @author ns019t + * + */ +@Component("capability-instance-operation") +public class CapabilityInstanceOperation extends AbstractOperation implements ICapabilityInstanceOperation { + + private static Logger log = LoggerFactory.getLogger(CapabilityOperation.class.getName()); + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + private CapabilityOperation capabilityOperation; + + /** + * String constants for logger + */ + private String statusIs = ". status is "; + private String dot = "."; + private String onGraph = " on graph "; + private String ofRI = " of resource instance "; + private String toCapability = " to capability "; + private String toCI = " to capability instance "; + private String toProperty = " to property "; + private String forRI = " for resource instance "; + private String failedCreateCI = "Failed to create capability instance of capability "; + private String failedAddProperties = "Failed to add properties to capability instance "; + private String ofCI = " of component instance "; + private String failedDeletePropertyValues = "Failed to delete property values of capability instance "; + private String toValue = " to property value "; + private String fromRI = " from resource instance "; + + /** + * create capability instance of capability with property values for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @param validateCapabilityInstExistence + * @param capabilityName + * @return + */ + @Override + public Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(String resourceInstanceId, String capabilityId, String capabilityName, + List<ComponentInstanceProperty> propertyValues, boolean validateCapabilityInstExistence) { + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + Wrapper<CapabilityData> overrideCapabilityDataWrapper = new Wrapper<>(); + Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper = new Wrapper<>(); + Either<CapabilityInstData, TitanOperationStatus> createCapabilityRes = null; + CapabilityInstData createdCapabilityInstance = null; + + Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper = new Wrapper<>(); + Either<ImmutablePair<CapabilityData, GraphEdge>, TitanOperationStatus> getCapabilityRes = null; + Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes = null; + Either<List<PropertyValueData>, TitanOperationStatus> addPropertyValuesRes = null; + Wrapper<String> createdCapabilityInstanceIdWrapper = new Wrapper<>(); + if (validateCapabilityInstExistence) { + validateCapabilityInstanceExistence(resourceInstanceId, capabilityId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityRes = getCapabilitiesOfResourceInstance(resourceInstanceId, capabilityId, capabilityName, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityDefinitionRes = getCapabiityDefinition(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, getCapabilityRes); + } + if (errorWrapper.isEmpty()) { + createCapabilityRes = createCapabilityInstanceOnGraph(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, overrideCapabilityDefinitionWrapper, getCapabilityDefinitionRes); + } + if (errorWrapper.isEmpty() && overrideCapabilityDefinitionWrapper.getInnerElement().getProperties() != null) { + createdCapabilityInstance = validateCapabilityInstanceProperties(resourceInstanceId, propertyValues, errorWrapper, overrideCapabilityDefinitionWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + if (errorWrapper.isEmpty()) { + addPropertyValuesRes = addPropertyValueToCapabilityInstance(resourceInstanceId, propertyValues, errorWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> result; + if (errorWrapper.isEmpty()) { + Map<CapabilityInstData, List<PropertyValueData>> resultMap = new HashMap<>(); + resultMap.put(createdCapabilityInstance, addPropertyValuesRes.left().value()); + result = Either.left(resultMap); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + @Override + public TitanOperationStatus createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + List<ComponentInstanceProperty> propertyValues, boolean validateCapabilityInstExistence) { + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + Wrapper<TitanVertex> overrideCapabilityDataWrapper = new Wrapper<>(); + Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper = new Wrapper<>(); + Either<TitanVertex, TitanOperationStatus> createCapabilityRes = null; + TitanVertex createdCapabilityInstance = null; + + Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper = new Wrapper<>(); + Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getCapabilityRes = null; + Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes = null; + TitanOperationStatus addPropertyValuesRes = null; + Wrapper<String> createdCapabilityInstanceIdWrapper = new Wrapper<>(); + if (validateCapabilityInstExistence) { + validateCapabilityInstanceExistence(resourceInstanceVertex, resourceInstanceId, capabilityId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityRes = getCapabilitiesOfResourceInstance(resourceInstanceVertex, resourceInstanceId, capabilityId, capabilityName, errorWrapper); + } + if (errorWrapper.isEmpty()) { + getCapabilityDefinitionRes = getCapabiityDefinitionByVertex(resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, getCapabilityRes); + } + if (errorWrapper.isEmpty()) { + createCapabilityRes = createCapabilityInstanceOnGraphByVertex(resourceInstanceVertex, resourceInstanceId, capabilityId, errorWrapper, overrideCapabilityDataWrapper, overrideCapabilityDefinitionWrapper, getCapabilityDefinitionRes); + } + if (errorWrapper.isEmpty() && overrideCapabilityDefinitionWrapper.getInnerElement().getProperties() != null) { + createdCapabilityInstance = validateCapabilityInstancePropertiesByVertex(resourceInstanceId, propertyValues, errorWrapper, overrideCapabilityDefinitionWrapper, createCapabilityRes.left().value(), defaultPropertiesWrapper, + createdCapabilityInstanceIdWrapper); + } + if (errorWrapper.isEmpty()) { + addPropertyValuesRes = addPropertyValueToCapabilityInstanceByVertex(resourceInstanceId, propertyValues, errorWrapper, createCapabilityRes, defaultPropertiesWrapper, createdCapabilityInstanceIdWrapper); + } + + return addPropertyValuesRes; + } + + private Either<List<PropertyValueData>, TitanOperationStatus> addPropertyValueToCapabilityInstance(String resourceInstanceId, List<ComponentInstanceProperty> propertyValues, Wrapper<TitanOperationStatus> errorWrapper, + Either<CapabilityInstData, TitanOperationStatus> createCapabilityRes, Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper, Wrapper<String> createdCapabilityInstanceIdWrapper) { + Either<List<PropertyValueData>, TitanOperationStatus> addPropertyValuesRes; + log.debug("Before adding property values to capability instance {} dot", createdCapabilityInstanceIdWrapper.getInnerElement()); + addPropertyValuesRes = addPropertyValuesToCapabilityInstance(createCapabilityRes.left().value(), propertyValues, defaultPropertiesWrapper.getInnerElement()); + if (addPropertyValuesRes.isRight()) { + errorWrapper.setInnerElement(addPropertyValuesRes.right().value()); + log.debug("failedAddProperties {} ofRI {} statusIs {} dot", createdCapabilityInstanceIdWrapper.getInnerElement(), resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After adding property values to capability instance {} status is {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), errorWrapper.getInnerElement()); + return addPropertyValuesRes; + } + + private TitanOperationStatus addPropertyValueToCapabilityInstanceByVertex(String resourceInstanceId, List<ComponentInstanceProperty> propertyValues, Wrapper<TitanOperationStatus> errorWrapper, + Either<TitanVertex, TitanOperationStatus> createCapabilityRes, Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper, Wrapper<String> createdCapabilityInstanceIdWrapper) { + log.trace("Before adding property values to capability instance {}", createdCapabilityInstanceIdWrapper.getInnerElement()); + TitanOperationStatus addPropertyValuesRes = addPropertyValuesToCapabilityInstance(createCapabilityRes.left().value(), propertyValues, defaultPropertiesWrapper.getInnerElement()); + if (!addPropertyValuesRes.equals(TitanOperationStatus.OK)) { + errorWrapper.setInnerElement(addPropertyValuesRes); + log.debug("Failed to add properties to capability instance {} {} {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After adding property values to capability instance {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), statusIs, errorWrapper.getInnerElement()); + return addPropertyValuesRes; + } + + private CapabilityInstData validateCapabilityInstanceProperties(String resourceInstanceId, List<ComponentInstanceProperty> propertyValues, Wrapper<TitanOperationStatus> errorWrapper, + Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper, Either<CapabilityInstData, TitanOperationStatus> createCapabilityRes, Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper, + Wrapper<String> createdCapabilityInstanceIdWrapper) { + CapabilityInstData createdCapabilityInstance; + createdCapabilityInstance = createCapabilityRes.left().value(); + createdCapabilityInstanceIdWrapper.setInnerElement(createdCapabilityInstance.getUniqueId()); + Map<String, PropertyDefinition> defaultProperties = overrideCapabilityDefinitionWrapper.getInnerElement().getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + defaultPropertiesWrapper.setInnerElement(defaultProperties); + log.debug("Before validating property values of capability instance {}.", createdCapabilityInstanceIdWrapper.getInnerElement()); + Either<Boolean, TitanOperationStatus> result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + errorWrapper.setInnerElement(result.right().value()); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After validating property values of capability instance {} status is {}.", createdCapabilityInstanceIdWrapper.getInnerElement(), errorWrapper.getInnerElement()); + return createdCapabilityInstance; + } + + private TitanVertex validateCapabilityInstancePropertiesByVertex(String resourceInstanceId, List<ComponentInstanceProperty> propertyValues, Wrapper<TitanOperationStatus> errorWrapper, + Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper, TitanVertex createCapabilityRes, Wrapper<Map<String, PropertyDefinition>> defaultPropertiesWrapper, Wrapper<String> createdCapabilityInstanceIdWrapper) { + String id = (String) titanGenericDao.getProperty(createCapabilityRes, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + createdCapabilityInstanceIdWrapper.setInnerElement(id); + Map<String, PropertyDefinition> defaultProperties = overrideCapabilityDefinitionWrapper.getInnerElement().getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + defaultPropertiesWrapper.setInnerElement(defaultProperties); + log.trace("Before validating property values of capability instance {}", createdCapabilityInstanceIdWrapper.getInnerElement()); + Either<Boolean, TitanOperationStatus> result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + errorWrapper.setInnerElement(result.right().value()); + log.debug("Failed to add properties to capability instance {} {} {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After validating property values of capability instance {} {} {}", createdCapabilityInstanceIdWrapper.getInnerElement(), statusIs, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceOnGraph(String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper, Wrapper<CapabilityData> overrideCapabilityDataWrapper, + Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper, Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes) { + Either<CapabilityInstData, TitanOperationStatus> createCapabilityRes; + log.debug("Before creating capability instance of capability {} on graph.", capabilityId); + overrideCapabilityDefinitionWrapper.setInnerElement(getCapabilityDefinitionRes.left().value()); + CapabilityInstData capabilityInstance = buildCapabilityInstanceData(resourceInstanceId, overrideCapabilityDefinitionWrapper.getInnerElement()); + createCapabilityRes = createCapabilityInstanceOnGraph(resourceInstanceId, overrideCapabilityDataWrapper.getInnerElement(), capabilityInstance); + if (createCapabilityRes.isRight()) { + errorWrapper.setInnerElement(createCapabilityRes.right().value()); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After creating capability instance of capability {} on graph. Status is {}", capabilityId, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either<TitanVertex, TitanOperationStatus> createCapabilityInstanceOnGraphByVertex(TitanVertex riVertex, String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper, + Wrapper<TitanVertex> overrideCapabilityDataWrapper, Wrapper<CapabilityDefinition> overrideCapabilityDefinitionWrapper, Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes) { + Either<TitanVertex, TitanOperationStatus> createCapabilityRes; + log.trace("Before creating capability instance of capability {} {}", capabilityId, onGraph); + overrideCapabilityDefinitionWrapper.setInnerElement(getCapabilityDefinitionRes.left().value()); + CapabilityInstData capabilityInstance = buildCapabilityInstanceData(resourceInstanceId, overrideCapabilityDefinitionWrapper.getInnerElement()); + createCapabilityRes = createCapabilityInstanceOnGraph(riVertex, resourceInstanceId, overrideCapabilityDataWrapper.getInnerElement(), capabilityInstance); + if (createCapabilityRes.isRight()) { + errorWrapper.setInnerElement(createCapabilityRes.right().value()); + log.debug("Failed to create capability instance of capability {} {} {} {} {} ", capabilityId, ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.debug("After creating capability instance of capability {} {} {} {} {}", capabilityId, onGraph, statusIs, errorWrapper.getInnerElement()); + return createCapabilityRes; + } + + private Either<CapabilityDefinition, TitanOperationStatus> getCapabiityDefinition(String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper, Wrapper<CapabilityData> overrideCapabilityDataWrapper, + Either<ImmutablePair<CapabilityData, GraphEdge>, TitanOperationStatus> getCapabilityRes) { + Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes; + log.debug("Before getting capability definition {} forRI {}.", capabilityId, resourceInstanceId); + CapabilityData overrideCapabilityData = getCapabilityRes.left().value().getLeft(); + overrideCapabilityDataWrapper.setInnerElement(overrideCapabilityData); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityDefinitionRes.right().value()); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability definition for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityDefinitionRes; + } + + private Either<CapabilityDefinition, TitanOperationStatus> getCapabiityDefinitionByVertex(String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper, Wrapper<TitanVertex> overrideCapabilityDataWrapper, + Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getCapabilityRes) { + Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes; + log.trace("Before getting capability definition {} {} {}", capabilityId, forRI, resourceInstanceId); + + TitanVertex overrideCapabilityData = getCapabilityRes.left().value().getLeft(); + + overrideCapabilityDataWrapper.setInnerElement(overrideCapabilityData); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityDefinitionRes.right().value()); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability definition for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityDefinitionRes; + } + + private Either<ImmutablePair<CapabilityData, GraphEdge>, TitanOperationStatus> getCapabilitiesOfResourceInstance(String resourceInstanceId, String capabilityId, String capabilityName, Wrapper<TitanOperationStatus> errorWrapper) { + Either<ImmutablePair<CapabilityData, GraphEdge>, TitanOperationStatus> getCapabilityRes; + log.debug("Before getting capability {} forRI {}.", capabilityId, resourceInstanceId); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + getCapabilityRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class, props); + if (getCapabilityRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityRes.right().value()); + log.debug("Failed to get capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + log.debug("After getting capability for {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + return getCapabilityRes; + } + + private Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getCapabilitiesOfResourceInstance(TitanVertex instanceVertex, String resourceInstanceId, String capabilityId, String capabilityName, + Wrapper<TitanOperationStatus> errorWrapper) { + Either<ImmutablePair<TitanVertex, Edge>, TitanOperationStatus> getCapabilityRes; + log.trace("Before getting capability {} {} {}", capabilityId, forRI, resourceInstanceId); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + getCapabilityRes = titanGenericDao.getChildByEdgeCriteria(instanceVertex, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (getCapabilityRes.isRight()) { + errorWrapper.setInnerElement(getCapabilityRes.right().value()); + log.debug("Failed to get capability {} {} {} {} {}", capabilityId, ofRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + } + log.trace("After getting capability for {} {} {} {} {}", capabilityId, forRI, resourceInstanceId, statusIs, errorWrapper.getInnerElement()); + return getCapabilityRes; + } + + private void validateCapabilityInstanceExistence(String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper) { + log.debug("Before validation of existence of capability instance of capability {} forRI {}.", capabilityId, resourceInstanceId); + boolean capabilityInstOfCapabilityAlreadyExists; + Either<Boolean, TitanOperationStatus> validateCapabilityInstExistenceRes = validateCapabilityInstExistence(resourceInstanceId, capabilityId); + if (validateCapabilityInstExistenceRes.isRight()) { + errorWrapper.setInnerElement(validateCapabilityInstExistenceRes.right().value()); + log.debug("Failed to validate uniqueness of capability instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } else { + capabilityInstOfCapabilityAlreadyExists = validateCapabilityInstExistenceRes.left().value(); + if (capabilityInstOfCapabilityAlreadyExists) { + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + } + log.debug("After validation of existence of capability instance of capability {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + + private void validateCapabilityInstanceExistence(TitanVertex resourceInstanceVertex, String resourceInstanceId, String capabilityId, Wrapper<TitanOperationStatus> errorWrapper) { + log.trace("Before validation of existence of capability instance of capability {} {} {}", capabilityId, forRI, resourceInstanceId); + boolean capabilityInstOfCapabilityAlreadyExists; + Either<Boolean, TitanOperationStatus> validateCapabilityInstExistenceRes = validateCapabilityInstExistence(resourceInstanceId, capabilityId); + if (validateCapabilityInstExistenceRes.isRight()) { + errorWrapper.setInnerElement(validateCapabilityInstExistenceRes.right().value()); + log.debug("Failed to validate uniqueness of capability instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } else { + capabilityInstOfCapabilityAlreadyExists = validateCapabilityInstExistenceRes.left().value(); + if (capabilityInstOfCapabilityAlreadyExists) { + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + log.debug("failedCreateCI {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + } + log.debug("After validation of existence of capability instance of capability {} forRI {} statusIs {}.", capabilityId, resourceInstanceId, errorWrapper.getInnerElement()); + } + + private Either<List<PropertyValueData>, TitanOperationStatus> addPropertyValuesToCapabilityInstance(CapabilityInstData createdCapabilityInstance, List<ComponentInstanceProperty> propertyValues, Map<String, PropertyDefinition> defaultProperties) { + TitanOperationStatus error = null; + List<PropertyValueData> createdPropertyValues = new ArrayList<>(); + for (ComponentInstanceProperty property : propertyValues) { + log.debug("Before adding property value {} toCI {}.", property.getName(), createdCapabilityInstance.getUniqueId()); + PropertyValueData propertyData = buildPropertyValueData(property.getName(), property.getType(), property.getValue(), createdCapabilityInstance.getUniqueId()); + Either<PropertyValueData, TitanOperationStatus> addPropertyValueRes = addPropertyValueToCapabilityInstance(createdCapabilityInstance, propertyData, defaultProperties.get(property.getName())); + if (addPropertyValueRes.isRight()) { + error = addPropertyValueRes.right().value(); + log.debug("Failed to add property to capability instance {} ofRI. StatusIs {}.", createdCapabilityInstance.getUniqueId(), error); + break; + } else { + createdPropertyValues.add(addPropertyValueRes.left().value()); + } + log.debug("After adding property value {} toCI {} statusIs {}", property.getName(), createdCapabilityInstance.getUniqueId(), error); + } + if (error == null) { + return Either.left(createdPropertyValues); + } + return Either.right(error); + } + + private TitanOperationStatus addPropertyValuesToCapabilityInstance(TitanVertex createdCapabilityInstancevertex, List<ComponentInstanceProperty> propertyValues, Map<String, PropertyDefinition> defaultProperties) { + TitanOperationStatus error = null; + String id = (String) titanGenericDao.getProperty(createdCapabilityInstancevertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + for (ComponentInstanceProperty property : propertyValues) { + log.trace("Before adding property value {} {} {}", property.getName(), toCI, id); + PropertyValueData propertyData = buildPropertyValueData(property.getName(), property.getType(), property.getValue(), id); + TitanOperationStatus addPropertyValueRes = addPropertyValueToCapabilityInstance(createdCapabilityInstancevertex, propertyData, defaultProperties.get(property.getName()), id); + if (!addPropertyValueRes.equals(TitanOperationStatus.OK)) { + error = addPropertyValueRes; + log.debug("Failed to add property to capability instance {} {} {} {}", id, ofRI, statusIs, error); + break; + } + log.debug("After adding property value {} {} {} {} {}", property.getName(), toCI, id, statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private PropertyValueData buildPropertyValueData(String propertyName, String propertyType, String propertyValue, String capabilityInstanceId) { + PropertyValueData propertyData = new PropertyValueData(); + String uniqueId = UniqueIdBuilder.buildPropertyValueUniqueId(capabilityInstanceId, propertyName); + Long creationTime = System.currentTimeMillis(); + propertyData.setUniqueId(uniqueId); + propertyData.setValue(propertyValue); + propertyData.setType(propertyType); + propertyData.setCreationTime(creationTime); + propertyData.setModificationTime(creationTime); + return propertyData; + } + + private Either<PropertyValueData, TitanOperationStatus> addPropertyValueToCapabilityInstance(CapabilityInstData createdCapabilityInstance, PropertyValueData propertyValue, PropertyDefinition propertyDefinition) { + TitanOperationStatus error = null; + Map<String, Object> props = null; + Either<GraphRelation, TitanOperationStatus> createRelationRes; + PropertyValueData createdValue = null; + log.debug("Before creating property value node {} onGraph.", propertyValue.getUniqueId()); + Either<PropertyValueData, TitanOperationStatus> createValueRes = titanGenericDao.createNode(propertyValue, PropertyValueData.class); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + log.debug("Failed to create property value for capability instance {} ofRI statusIs {}.", createdCapabilityInstance.getUniqueId(), error); + } + log.debug("After creating property value node {} onGraph statusIs {}.", propertyValue.getUniqueId(), error); + if (error == null) { + log.debug("Before creating relation from property value node {} toCI {}.", propertyValue.getUniqueId(), createdCapabilityInstance.getUniqueId()); + createdValue = createValueRes.left().value(); + props = new HashMap<>(); + props.put(GraphPropertiesDictionary.PROPERTY_NAME.name(), propertyDefinition.getName()); + props.put(GraphPropertiesDictionary.PROPERTY_ID.name(), propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdCapabilityInstance, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from capability instance {} toValue {} statusIs {}.", createdCapabilityInstance.getUniqueId(), createdValue.getUniqueId(), error); + } + log.debug("After creating relation from property value node {} toCI {} statusIs {}.", propertyValue.getUniqueId(), createdCapabilityInstance.getUniqueId(), error); + } + if (error == null) { + log.debug("Before creating relation from property value node {} toProperty {}.", propertyValue.getUniqueId(), propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(propertyValue, new PropertyData(propertyDefinition, null), GraphEdgeLabels.PROPERTY_IMPL, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from property value {} toProperty {} statusIs {}.", createdValue.getUniqueId(), propertyDefinition.getUniqueId(), error); + } + log.debug("After creating relation from property value node {} toProperty statusIs {}.", propertyValue.getUniqueId(), propertyDefinition.getUniqueId(), error); + } + if (error == null) { + return Either.left(createdValue); + } + return Either.right(error); + } + + private TitanOperationStatus addPropertyValueToCapabilityInstance(TitanVertex createdCapabilityInstanceVertex, PropertyValueData propertyValue, PropertyDefinition propertyDefinition, String id) { + TitanOperationStatus error = null; + Map<String, Object> props = null; + TitanOperationStatus createRelationRes; + log.trace("Before creating property value node {} on graph.", propertyValue.getUniqueId()); + Either<TitanVertex, TitanOperationStatus> createValueRes = titanGenericDao.createNode(propertyValue); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + if (log.isDebugEnabled()){ + log.debug("Failed to create property value for capability instance {} {} {} {}", id, ofRI, statusIs, error); + } + } + log.trace("After creating property value node {} on graph status is {}", propertyValue.getUniqueId(), error); + TitanVertex createdPropVertex = null; + String createdId = null; + if (error == null) { + log.trace("Before creating relation from property value node {} {} {} ", propertyValue.getUniqueId(), toCI, id); + props = new HashMap<>(); + props.put(GraphPropertiesDictionary.PROPERTY_NAME.name(), propertyDefinition.getName()); + props.put(GraphPropertiesDictionary.PROPERTY_ID.name(), propertyDefinition.getUniqueId()); + createdPropVertex = createValueRes.left().value(); + createRelationRes = titanGenericDao.createEdge(createdCapabilityInstanceVertex, createdPropVertex, GraphEdgeLabels.PROPERTY_VALUE, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + createdId = (String) titanGenericDao.getProperty(createdPropVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from capability instance {} {} {} {} {}", id, toValue, createdId, statusIs, error); + } + } + if (log.isTraceEnabled()){ + log.trace("After creating relation from property value node {} {} {} {} {}", propertyValue.getUniqueId(), toCI, id, statusIs, error); + } + } + if (error == null) { + log.trace("Before creating relation from property value node {} {} {}", propertyValue.getUniqueId(), toProperty, propertyDefinition.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(createdPropVertex, new PropertyData(propertyDefinition, null), GraphEdgeLabels.PROPERTY_IMPL, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to create relation from property value {} {} {} {} {}", createdId, toProperty, propertyDefinition.getUniqueId(), statusIs, error); + } + log.debug("After creating relation from property value node {} {} {} {} {}", propertyValue.getUniqueId(), toProperty, propertyDefinition.getUniqueId(), statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private Either<Boolean, TitanOperationStatus> validateCapabilityInstanceProperties(Map<String, PropertyDefinition> defaultProperties, List<ComponentInstanceProperty> propertyValues) { + Either<Boolean, TitanOperationStatus> result = Either.left(true); + for (ComponentInstanceProperty property : propertyValues) { + result = validateUpdateCapabilityInstancePropertyValue(property, defaultProperties); + if (result.isRight()) { + break; + } + } + return result; + } + + private Either<Boolean, TitanOperationStatus> validateUpdateCapabilityInstancePropertyValue(ComponentInstanceProperty property, Map<String, PropertyDefinition> defaultProperties) { + PropertyDefinition defaultProperty; + String propertyName = property.getName(); + Either<Boolean, TitanOperationStatus> result = null; + if (defaultProperties.containsKey(propertyName)) { + defaultProperty = defaultProperties.get(propertyName); + String propertyType = property.getType() == null || property.getType().isEmpty() ? defaultProperty.getType() : property.getType(); + + String innerType = null; + if (property.getSchema() != null && property.getSchema().getProperty() != null) + innerType = property.getSchema().getProperty().getType(); + if (innerType == null && defaultProperty.getSchema() != null && defaultProperty.getSchema().getProperty() != null) + innerType = defaultProperty.getSchema().getProperty().getType(); + + if (defaultProperty.getType().equals(propertyType)) { + String propertyValue = property.getValue(); + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Failed to update property value statusIs {}.", status); + result = Either.right(status); + } + if (result == null) { + Either<Object, Boolean> updatedPropertyValueRes = propertyOperation.validateAndUpdatePropertyValue(propertyType, propertyValue, innerType, allDataTypes.left().value()); + if (updatedPropertyValueRes.isLeft()) { + if (updatedPropertyValueRes.left().value() != null) + property.setDefaultValue(updatedPropertyValueRes.left().value().toString()); + result = Either.left(true); + } else { + result = Either.right(TitanOperationStatus.INVALID_PROPERTY); + } + } + log.debug("The property with name {} has invalid type {} or invalid value {}.", propertyName, propertyType, propertyValue); + + } else { + result = Either.right(TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS); + log.debug("The property with name {} and different type already exists.", propertyName); + } + } else { + result = Either.right(TitanOperationStatus.NOT_FOUND); + log.debug("Failed to find property with name {}.", propertyName); + } + return result; + } + + /** + * validate capability instance uniqueness + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + @Override + public Either<Boolean, TitanOperationStatus> validateCapabilityInstExistence(String resourceInstanceId, String capabilityId) { + Either<Boolean, TitanOperationStatus> result = null; + TitanOperationStatus error; + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either<Edge, TitanOperationStatus> getCapabilityInstanceEdgeRes = titanGenericDao.getOutgoingEdgeByCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CAPABILITY_INST, props); + if (getCapabilityInstanceEdgeRes.isRight()) { + error = getCapabilityInstanceEdgeRes.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.left(false); + } else { + log.debug("Failed to get outgoing edge for resource instance {} statusIs {}.", resourceInstanceId, error); + result = Either.right(error); + } + } + if (result == null) { + result = Either.left(true); + } + return result; + } + + @Override + public Either<Boolean, TitanOperationStatus> validateCapabilityInstExistence(TitanVertex instanceVertex, String resourceInstanceId, String capabilityId) { + Either<Boolean, TitanOperationStatus> result = null; + TitanOperationStatus error; + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either<Edge, TitanOperationStatus> getCapabilityInstanceEdgeRes = titanGenericDao.getOutgoingEdgeByCriteria(instanceVertex, GraphEdgeLabels.CAPABILITY_INST, props); + if (getCapabilityInstanceEdgeRes.isRight()) { + error = getCapabilityInstanceEdgeRes.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.left(false); + } else { + log.debug("Failed to get outgoing edge for resource instance {} {} {}", resourceInstanceId, statusIs, error); + result = Either.right(error); + } + } + if (result == null) { + result = Either.left(true); + } + return result; + } + + private Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceOnGraph(String resourceInstanceId, CapabilityData overrideCapabilityData, CapabilityInstData capabilityInstance) { + log.debug("Before creation of capability instance of capability {} forRI {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId); + + Either<GraphRelation, TitanOperationStatus> createRelationRes; + CapabilityInstData createdCapabilityInstance = null; + String capabilityInstanceId = null; + TitanOperationStatus error = null; + Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceRes = titanGenericDao.createNode(capabilityInstance, CapabilityInstData.class); + if (createCapabilityInstanceRes.isRight()) { + error = createCapabilityInstanceRes.right().value(); + log.debug("failedCreateCI {} forRI {} statusIs {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId, error); + } + log.debug("After creation of capability instance of capability {} forRI {} statusIs {}.", overrideCapabilityData.getUniqueId(), resourceInstanceId, error); + if (error == null) { + createdCapabilityInstance = createCapabilityInstanceRes.left().value(); + capabilityInstanceId = createdCapabilityInstance.getUniqueId(); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityData.getUniqueId()); + UniqueIdData resourceInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, resourceInstanceId); + log.debug("Before associating resource instance {} to capability instance.", resourceInstanceId); + createRelationRes = titanGenericDao.createRelation(resourceInstanceIdData, capabilityInstance, GraphEdgeLabels.CAPABILITY_INST, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to assotiate resource instance {} toCI {} statusIs {}.", resourceInstanceId, capabilityInstanceId, error); + } + log.debug("After associating resource instance {} to CI {} statusIs {}.", resourceInstanceId, capabilityInstanceId, error); + } + if (error == null) { + log.debug("Before associating capability instance {} toCapability {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId()); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityData.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdCapabilityInstance, overrideCapabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to associate capability instance {} toCapability statusIs {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId(), error); + } + log.debug("After associating capability instance {} toCapability statusIs {}.", capabilityInstanceId, overrideCapabilityData.getUniqueId(), error); + } + if (error == null) { + return createCapabilityInstanceRes; + } + return Either.right(error); + } + + private Either<TitanVertex, TitanOperationStatus> createCapabilityInstanceOnGraph(TitanVertex riVertex, String resourceInstanceId, TitanVertex overrideCapabilityDataVertex, CapabilityInstData capabilityInstance) { + String overrideCapabilityDataId = (String) titanGenericDao.getProperty(overrideCapabilityDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + log.trace("Before creation of capability instance of capability {} {} {}", overrideCapabilityDataVertex, forRI, resourceInstanceId); + + TitanOperationStatus createRelationRes; + TitanVertex createdCapabilityInstance = null; + String capabilityInstanceId = null; + TitanOperationStatus error = null; + Either<TitanVertex, TitanOperationStatus> createCapabilityInstanceRes = titanGenericDao.createNode(capabilityInstance); + if (createCapabilityInstanceRes.isRight()) { + error = createCapabilityInstanceRes.right().value(); + log.debug("Failed to create capability instance of capability {} {} {} {} {}", overrideCapabilityDataId, forRI, resourceInstanceId, statusIs, error); + } + log.trace("After creation of capability instance of capability {} {} {} {} {}", overrideCapabilityDataId, forRI, resourceInstanceId, statusIs, error); + if (error == null) { + createdCapabilityInstance = createCapabilityInstanceRes.left().value(); + capabilityInstanceId = (String) titanGenericDao.getProperty(createdCapabilityInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityDataId); + log.debug("Before associating resource instance {} to capability instance.", resourceInstanceId); + + createRelationRes = titanGenericDao.createEdge(riVertex, capabilityInstance, GraphEdgeLabels.CAPABILITY_INST, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to assotiate resource instance {} {} {} {} {}", resourceInstanceId, toCI, capabilityInstanceId, statusIs, error); + } + if (log.isTraceEnabled()) { + log.trace("After associating resource instance {} {} {} {} {}", resourceInstanceId, toCI, capabilityInstanceId, statusIs, error); + } + } + if (error == null) { + log.trace("Before associating capability instance {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), overrideCapabilityDataId); + createRelationRes = titanGenericDao.createEdge(createdCapabilityInstance, overrideCapabilityDataVertex, GraphEdgeLabels.INSTANCE_OF, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + log.debug("Failed to associate capability instance {} {} {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId, statusIs, error); + } + log.debug("After associating capability instance {} {} {} {} {}", capabilityInstanceId, toCapability, overrideCapabilityDataId, statusIs, error); + } + if (error == null) { + return createCapabilityInstanceRes; + } + return Either.right(error); + } + + private CapabilityInstData buildCapabilityInstanceData(String resourceInstanceId, CapabilityDefinition capability) { + CapabilityInstData capabilityInstance = new CapabilityInstData(); + Long creationTime = System.currentTimeMillis(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(resourceInstanceId, capability.getName()); + + capabilityInstance.setCreationTime(creationTime); + capabilityInstance.setModificationTime(creationTime); + capabilityInstance.setUniqueId(uniqueId); + + return capabilityInstance; + } + + /** + * delete capability instance from resource instance + * + * @param resourceInstanceId + * @param capabilityInstanceId + * @return + */ + @Override + public Either<CapabilityInstData, TitanOperationStatus> deleteCapabilityInstanceFromResourceInstance(String resourceInstanceId, String capabilityInstanceId) { + log.debug("Before deleting of capability instance {} fromRI {}.", capabilityInstanceId, resourceInstanceId); + + Either<CapabilityInstData, TitanOperationStatus> deleteCapabilityInstRes = null; + TitanOperationStatus error = null; + Either<Boolean, TitanOperationStatus> deleteProperyValuesRes = deleteAllPropertyValuesOfCapabilityInstance(resourceInstanceId, capabilityInstanceId); + if (deleteProperyValuesRes.isRight()) { + error = deleteProperyValuesRes.right().value(); + log.debug("failedDeletePropertyValues {} for RI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + deleteCapabilityInstRes = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstanceId, CapabilityInstData.class); + if (deleteCapabilityInstRes.isRight()) { + error = deleteCapabilityInstRes.right().value(); + log.debug("Failed to delete capability instance {} forRI {} statusIs {}", capabilityInstanceId, resourceInstanceId, error); + } + } + log.debug("After deleting of capability instance {} fromRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + if (error == null) { + return Either.left(deleteCapabilityInstRes.left().value()); + } + return Either.right(error); + } + + private Either<Boolean, TitanOperationStatus> deleteAllPropertyValuesOfCapabilityInstance(String resourceInstanceId, String capabilityInstanceId) { + log.debug("Before deleting all property values of capability instance {} fromRI {}.", capabilityInstanceId, resourceInstanceId); + TitanOperationStatus error = null; + List<ImmutablePair<PropertyValueData, GraphEdge>> deletePropertiesPairs; + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstanceId, + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {} forRI {} status {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + deletePropertiesPairs = getPropertyValuesRes.left().value(); + for (ImmutablePair<PropertyValueData, GraphEdge> propertyPair : deletePropertiesPairs) { + Either<PropertyValueData, TitanOperationStatus> deletePropertyRes = titanGenericDao.deleteNode(propertyPair.getLeft(), PropertyValueData.class); + if (deletePropertyRes.isRight()) { + error = deletePropertyRes.right().value(); + log.debug("failedDeletePropertyValues {} forRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + break; + } + } + } + log.debug("After deleting all property values of capability instance {} fromRI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + if (error == null) { + return Either.left(true); + } + return Either.right(error); + } + + /** + * get all capability instances for resource instance returns all Capability Instances related to Resource Instance as List<CapabilityInstData> or TitanOperationStatus if error occurs or if Resource Instance have no any related Capability + * Instance + * + * @param resourceInstanceId + * @return Either<List<CapabilityInstData>, TitanOperationStatus> + */ + @Override + public Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getAllCapabilityInstancesOfResourceInstance(String resourceInstanceId) { + log.debug("Before deleting all capability instances of resource instance {}.", resourceInstanceId); + TitanOperationStatus error = null; + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight()) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {} statusIs {}.", resourceInstanceId, error); + } + log.debug("After deleting all capability instances of resource instance {} statusIs {}", resourceInstanceId, error); + if (error == null) { + return getCapabilityInstancesRes; + } + return Either.right(error); + } + + /** + * get capability instance of capability for resource instance + * + * @param resourceInstanceId + * @param capabilityId + * @return + */ + @Override + public Either<CapabilityInstData, TitanOperationStatus> getCapabilityInstanceOfCapabilityOfResourceInstance(String resourceInstanceId, String capabilityId) { + TitanOperationStatus error = null; + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either<ImmutablePair<CapabilityInstData, GraphEdge>, TitanOperationStatus> getCapabilityInstanceRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class, props); + if (getCapabilityInstanceRes.isRight()) { + error = getCapabilityInstanceRes.right().value(); + log.debug("Failed to retrieve capability Instance of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + return Either.left(getCapabilityInstanceRes.left().value().getLeft()); + } + return Either.right(error); + } + + /** + * update capability property values + * + * @param resourceInstanceId + * @param propertyValues + * @param capabilityId + * @return + */ + @Override + public Either<List<PropertyValueData>, TitanOperationStatus> updateCapabilityPropertyValues(String resourceInstanceId, String capabilityId, List<ComponentInstanceProperty> propertyValues) { + log.debug("Before updating property values of capability {} ofRI {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Map<String, Object> props = new HashMap<>(); + CapabilityInstData capabilityInstance = null; + String capabilityInstanceId = null; + Either<Boolean, TitanOperationStatus> deleteProperyValuesRes; + + CapabilityData overrideCapabilityData; + CapabilityDefinition overrideCapabilityDefinition; + Map<String, PropertyDefinition> defaultProperties = null; + Either<ImmutablePair<CapabilityData, GraphEdge>, TitanOperationStatus> getCapabilityDataRes = null; + Either<List<PropertyValueData>, TitanOperationStatus> addPropertyValuesRes = null; + Either<CapabilityDefinition, TitanOperationStatus> getCapabilityDefinitionRes = null; + + log.debug("Before getting all capability instances of RI {}.", resourceInstanceId); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityId); + Either<ImmutablePair<CapabilityInstData, GraphEdge>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class, props); + if (getCapabilityInstancesRes.isRight()) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + log.debug("After getting all capability instances ofRI {} statusIs {}.", resourceInstanceId, error); + if (error == null) { + log.debug("Before deleting all capability instances ofRI {}.", resourceInstanceId); + capabilityInstance = getCapabilityInstancesRes.left().value().getLeft(); + capabilityInstanceId = capabilityInstance.getUniqueId(); + deleteProperyValuesRes = deleteAllPropertyValuesOfCapabilityInstance(resourceInstanceId, capabilityInstanceId); + if (deleteProperyValuesRes.isRight()) { + error = deleteProperyValuesRes.right().value(); + log.debug("failedDeletePropertyValues {} forRI {} statusIs {}", capabilityInstanceId, resourceInstanceId, statusIs, error); + } + log.debug("After deleting all capability instances ofRI {} statusIs {}.", resourceInstanceId, error); + } + if (error == null) { + log.debug("Before getting capability {} ofRI {}.", capabilityId, resourceInstanceId); + getCapabilityDataRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + if (getCapabilityDataRes.isRight()) { + error = getCapabilityDataRes.right().value(); + log.debug("Failed to get capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + log.debug("After getting capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before getting capability definition for capability {} ofRI {}.", capabilityId, resourceInstanceId); + overrideCapabilityData = getCapabilityDataRes.left().value().getLeft(); + getCapabilityDefinitionRes = capabilityOperation.getCapabilityByCapabilityData(overrideCapabilityData); + if (getCapabilityDefinitionRes.isRight()) { + error = getCapabilityDefinitionRes.right().value(); + log.debug("Failed to retrieve capability {} ofRI {} statusIs {}", capabilityId, resourceInstanceId, error); + } + log.debug("After getting capability definition for capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before validating capability properties of capability instance {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + overrideCapabilityDefinition = getCapabilityDefinitionRes.left().value(); + if (overrideCapabilityDefinition.getProperties() != null) { + defaultProperties = overrideCapabilityDefinition.getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + } + Either<Boolean, TitanOperationStatus> result = validateCapabilityInstanceProperties(defaultProperties, propertyValues); + if (result.isRight()) { + error = result.right().value(); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", capabilityInstance.getUniqueId(), resourceInstanceId, error); + } + log.debug("After validating capability properties of capability instance {} of RI {} statusIs {}.", capabilityInstanceId, resourceInstanceId, error); + } + if (error == null) { + log.debug("Before adding property values toCI {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + addPropertyValuesRes = addPropertyValuesToCapabilityInstance(capabilityInstance, propertyValues, defaultProperties); + if (addPropertyValuesRes.isRight()) { + error = addPropertyValuesRes.right().value(); + log.debug("failedAddProperties {} ofRI {} statusIs {}.", capabilityInstance.getUniqueId(), resourceInstanceId, error); + } + log.debug("Before adding property values toCI {} ofRI {}.", capabilityInstanceId, resourceInstanceId); + } + log.debug("After updating property values of capability {} ofRI {} statusIs {}.", capabilityId, resourceInstanceId, error); + if (error == null) { + return addPropertyValuesRes; + } + return Either.right(error); + } + + /** + * clone and associate capability instance with property values + * + * @param createdComponentInstance + * @param capability + * @param capabilityInstPair + * @return + */ + @Override + public Either<ImmutablePair<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> cloneAssociateCapabilityInstanceWithPropertyValues(ComponentInstanceData createdComponentInstance, CapabilityDefinition capability, + ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstPair) { + + TitanOperationStatus error = null; + String componentInstanceId = createdComponentInstance.getUniqueId(); + String capabilityInstanceId = capabilityInstPair.getLeft().getUniqueId(); + + log.debug("Before cloning capability instance with property values of capability instance {} ofRI {}.", capabilityInstanceId, componentInstanceId); + List<ImmutablePair<PropertyValueData, GraphEdge>> propertyValuePairs; + List<PropertyValueData> newPropertyValues = new ArrayList<>(); + CapabilityInstData cloneCapabilityInstance = null; + Either<CapabilityInstData, TitanOperationStatus> cloneCapabilityInstanceNodeRes = null; + + log.debug("Before getting all property values ofCI {} ofRI {}.", capabilityInstanceId, componentInstanceId); + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstPair.getLeft().getUniqueId(), + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {} ofCI {} statusIs {}.", capabilityInstPair.getLeft().getUniqueId(), componentInstanceId ,error); + } + log.debug("After getting all property values ofCI {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + CapabilityInstData cloneCapabilityInst = buildCapabilityInstanceData(componentInstanceId, capability); + log.debug("Before creating capability instance node {} onGraph.", cloneCapabilityInst.getUniqueId()); + cloneCapabilityInstanceNodeRes = titanGenericDao.createNode(cloneCapabilityInst, CapabilityInstData.class); + if (cloneCapabilityInstanceNodeRes.isRight()) { + error = cloneCapabilityInstanceNodeRes.right().value(); + log.debug("Failed to create capability instance of capability {} ofCI {} statusIs {}.", capability.getUniqueId(), componentInstanceId, error); + } + log.debug("After creating capability instance node {} onGraph. statusIs {}", cloneCapabilityInst.getUniqueId(), error); + } + + if (error == null) { + log.debug("Before creating relation from capability instance {} toCapability {} onGraph.", cloneCapabilityInstanceNodeRes.left().value().getUniqueId(), capability.getUniqueId()); + cloneCapabilityInstance = cloneCapabilityInstanceNodeRes.left().value(); + CapabilityData capabilityData = buildCapabilityData(capability); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityData.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> createRelationRes = titanGenericDao.createRelation(cloneCapabilityInstance, capabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to associate capability instance {} toCapability {} statusIs {}.", cloneCapabilityInstance.getUniqueId(), capability.getUniqueId(), error); + } + log.debug("After creating relation from capability instance {} toCapability {} onGraph. statusIs {}.", cloneCapabilityInstanceNodeRes.left().value().getUniqueId(), capability.getUniqueId(), error); + } + + if (error == null) { + log.debug("Before cloning property values ofCI {}.", capabilityInstanceId); + propertyValuePairs = getPropertyValuesRes.left().value(); + for (ImmutablePair<PropertyValueData, GraphEdge> propertyValuePair : propertyValuePairs) { + Either<PropertyValueData, TitanOperationStatus> clonePropertyValueRes = cloneAssociatePropertyValue(cloneCapabilityInstance, propertyValuePair); + if (clonePropertyValueRes.isRight()) { + error = clonePropertyValueRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to clone property value {} ofCapability {} ofCI {}. statusIs {}.", propertyValuePair.getLeft().getUniqueId(), capability.getUniqueId(), componentInstanceId, error); + } + break; + } else { + newPropertyValues.add(clonePropertyValueRes.left().value()); + } + } + log.debug("After cloning property values of CI {} statusIs {}.", capabilityInstanceId, error); + } + log.debug("After cloning capability instance with property values of capability instance {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + return Either.left(new ImmutablePair<CapabilityInstData, List<PropertyValueData>>(cloneCapabilityInstance, newPropertyValues)); + } + return Either.right(error); + } + + public Either<TitanVertex, TitanOperationStatus> cloneAssociateCapabilityInstanceWithPropertyValues(TitanVertex componentInstanceVertex, CapabilityDefinition capability, ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstPair) { + + TitanOperationStatus error = null; + String componentInstanceId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String capabilityInstanceId = capabilityInstPair.getLeft().getUniqueId(); + + if (log.isTraceEnabled()) { + log.trace("Before cloning capability instance with property values of capability instance {} {} {}", capabilityInstanceId, ofRI, componentInstanceId); + } + List<ImmutablePair<TitanVertex, Edge>> propertyValuePairs; + Either<TitanVertex, TitanOperationStatus> cloneCapabilityInstanceNodeRes = null; + + if (log.isTraceEnabled()) { + log.trace("Before getting all property values {} {} {} {}", ofCI, capabilityInstanceId, ofRI, componentInstanceId); + } + Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> getPropertyValuesRes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), capabilityInstPair.getLeft().getUniqueId(), + GraphEdgeLabels.PROPERTY_VALUE); + if (getPropertyValuesRes.isRight()) { + error = getPropertyValuesRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to retrieve property values of capability instance {} {} {} {} {}", capabilityInstPair.getLeft().getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After getting all property values {} {} {} {} {} {}", ofCI, capabilityInstanceId, ofRI, componentInstanceId, statusIs, error); + } + if (error == null) { + CapabilityInstData cloneCapabilityInst = buildCapabilityInstanceData(componentInstanceId, capability); + log.trace("Before creating capability instance node {} {} ", cloneCapabilityInst.getUniqueId(), onGraph); + cloneCapabilityInstanceNodeRes = titanGenericDao.createNode(cloneCapabilityInst); + if (cloneCapabilityInstanceNodeRes.isRight()) { + error = cloneCapabilityInstanceNodeRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to create capability instance of capability {} {} {} {} {}", capability.getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating capability instance node {} {} {} {}", cloneCapabilityInst.getUniqueId(), onGraph, statusIs, error); + } + } + CapabilityData capabilityData; + TitanVertex cloneCapabilityInstance = null; + if (error == null) { + if (log.isTraceEnabled()) { + log.trace("Before creating relation from capability instance {} {} {} {}", capability.getUniqueId(), toCapability, capability.getUniqueId(), onGraph); + } + capabilityData = buildCapabilityData(capability); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CAPABILITY_ID.getProperty(), capabilityData.getUniqueId()); + cloneCapabilityInstance = cloneCapabilityInstanceNodeRes.left().value(); + TitanOperationStatus createRelationRes = titanGenericDao.createEdge(cloneCapabilityInstance, capabilityData, GraphEdgeLabels.INSTANCE_OF, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to associate capability instance {} {} {} {} {}", capabilityData.getUniqueId(), toCapability, capability.getUniqueId(), statusIs, createRelationRes); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating relation from capability instance {} {} {} {} {} {}", capabilityData.getUniqueId(), toCapability, capability.getUniqueId(), onGraph, statusIs, error); + } + } + + if (error == null) { + log.trace("Before cloning property values {} {} ", ofCI, capabilityInstanceId); + propertyValuePairs = getPropertyValuesRes.left().value(); + for (ImmutablePair<TitanVertex, Edge> propertyValuePair : propertyValuePairs) { + TitanOperationStatus clonePropertyValueRes = cloneAssociatePropertyValue(cloneCapabilityInstance, propertyValuePair); + if (!clonePropertyValueRes.equals(TitanOperationStatus.OK)) { + error = clonePropertyValueRes; + if (log.isDebugEnabled()) { + log.debug("Failed to clone property value of capability {} {} {} {} {}", capability.getUniqueId(), ofCI, componentInstanceId, statusIs, error); + } + break; + } + } + if (log.isDebugEnabled()) { + log.debug("After cloning property values {} {} {} {}", ofCI, capabilityInstanceId, statusIs, error); + } + } + log.debug("After cloning capability instance with property values of capability instance {} ofRI {} statusIs {}.", capabilityInstanceId, componentInstanceId, error); + if (error == null) { + return Either.left(cloneCapabilityInstance); + } + return Either.right(error); + } + + private CapabilityData buildCapabilityData(CapabilityDefinition capability) { + CapabilityData capabilityData = new CapabilityData(); + capabilityData.setUniqueId(capability.getUniqueId()); + capabilityData.setDescription(capability.getDescription()); + capabilityData.setType(capability.getType()); + capabilityData.setMaxOccurrences(capability.getMaxOccurrences()); + capabilityData.setMinOccurrences(capability.getMinOccurrences()); + List<String> validSourceTypes = capability.getValidSourceTypes(); + if (validSourceTypes != null) { + capabilityData.setValidSourceTypes(validSourceTypes); + } + return capabilityData; + } + + private Either<PropertyValueData, TitanOperationStatus> cloneAssociatePropertyValue(CapabilityInstData cloneCapabilityInstance, ImmutablePair<PropertyValueData, GraphEdge> propertyValuePair) { + TitanOperationStatus error = null; + String propertyValueID = propertyValuePair.getLeft().getUniqueId(); + String capabilityInstanceId = cloneCapabilityInstance.getUniqueId(); + log.debug("Before cloning property values {} ofCI {}.", propertyValueID, capabilityInstanceId); + + Map<String, Object> props = propertyValuePair.getRight().getProperties(); + PropertyData propertyData = new PropertyData(); + String propertyId = (String) props.get(GraphPropertiesDictionary.PROPERTY_ID.name()); + propertyData.getPropertyDataDefinition().setUniqueId(propertyId); + + PropertyValueData propertyValue = buildPropertyValueData((String) props.get(GraphPropertiesDictionary.PROPERTY_NAME.name()), propertyValuePair.getLeft().getType(), propertyValuePair.getLeft().getValue(), capabilityInstanceId); + PropertyValueData createdValue = null; + Either<GraphRelation, TitanOperationStatus> createRelationRes; + + log.debug("Before creating property values node {} onGraph.", propertyValue.getUniqueId()); + Either<PropertyValueData, TitanOperationStatus> createValueRes = titanGenericDao.createNode(propertyValue, PropertyValueData.class); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + log.debug("Failed to create property value for capability instance {} ofRI. statusIs {}.", cloneCapabilityInstance.getUniqueId(), error); + } + log.debug("After creating property values node {} onGraph. statusIs {}.", propertyValue.getUniqueId(), error); + if (error == null) { + createdValue = createValueRes.left().value(); + log.debug("Before creating relation from capability instance {} toValue {}.", capabilityInstanceId, createdValue.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(cloneCapabilityInstance, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from capability instance {} toValue {} statusIs {}.", cloneCapabilityInstance.getUniqueId(), createdValue.getUniqueId(), error); + } + log.debug("After creating relation from capability instance {} toValue {} statusIs {}", capabilityInstanceId, createdValue.getUniqueId(), error); + } + if (error == null) { + log.debug("Before creating relation from property value {} toProperty {}.", createdValue, propertyData.getUniqueId()); + createRelationRes = titanGenericDao.createRelation(createdValue, propertyData, GraphEdgeLabels.PROPERTY_IMPL, props); + if (createRelationRes.isRight()) { + error = createRelationRes.right().value(); + log.debug("Failed to create relation from property value {} toProperty {} statusIs {}.", createdValue.getUniqueId(), propertyId, error); + } + log.debug("Before creating relation from property value {} toProperty {} statusIs {}.", createdValue, propertyData.getUniqueId(), error); + } + log.debug("After cloning property values {} ofCI {} statusIs {}.", propertyValueID, capabilityInstanceId, error); + if (error == null) { + return Either.left(createdValue); + } + return Either.right(error); + } + + private TitanOperationStatus cloneAssociatePropertyValue(TitanVertex capabilityInstanceVertex, ImmutablePair<TitanVertex, Edge> propertyValuePair) { + TitanOperationStatus error = null; + TitanVertex propertyVertex = propertyValuePair.getLeft(); + String propertyValueID = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String capabilityInstanceId = (String) titanGenericDao.getProperty(capabilityInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (log.isTraceEnabled()) { + log.trace("Before cloning property values {} {} {}", propertyValueID, ofCI, capabilityInstanceId); + } + + Map<String, Object> props = titanGenericDao.getProperties(propertyValuePair.getRight()); + PropertyData propertyData = new PropertyData(); + String propertyId = (String) props.get(GraphPropertiesDictionary.PROPERTY_ID.name()); + propertyData.getPropertyDataDefinition().setUniqueId(propertyId); + + String propertyType = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.TYPE.getProperty()); + String propertyValueStr = (String) titanGenericDao.getProperty(propertyVertex, GraphPropertiesDictionary.VALUE.getProperty()); + + PropertyValueData propertyValue = buildPropertyValueData((String) props.get(GraphPropertiesDictionary.PROPERTY_NAME.name()), propertyType, propertyValueStr, capabilityInstanceId); + TitanVertex createdValue = null; + TitanOperationStatus createRelationRes; + + log.trace("Before creating property values node {} {} ", propertyValue.getUniqueId(), onGraph); + Either<TitanVertex, TitanOperationStatus> createValueRes = titanGenericDao.createNode(propertyValue); + String capabiltyInstId = (String) titanGenericDao.getProperty(capabilityInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (createValueRes.isRight()) { + error = createValueRes.right().value(); + if (log.isDebugEnabled()) { + log.debug("Failed to create property value for capability instance {} {} {} {}", capabiltyInstId, ofRI, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating property values node {} {} {} {} ", propertyValue.getUniqueId(), onGraph, statusIs, error); + } + if (error == null) { + createdValue = createValueRes.left().value(); + log.trace("Before creating relation from capability instance {} {} {}", capabilityInstanceId, toValue, propertyValue.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(capabilityInstanceVertex, createdValue, GraphEdgeLabels.PROPERTY_VALUE, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from capability instance {} {} {} {} {}", capabiltyInstId, toValue, propertyValue.getUniqueId(), statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After creating relation from capability instance {} {} {} {} {} ", capabilityInstanceId, toValue, propertyValue.getUniqueId(), statusIs, error); + } + } + if (error == null) { + log.trace("Before creating relation from property value {} {} {} ", createdValue, toProperty, propertyData.getUniqueId()); + createRelationRes = titanGenericDao.createEdge(createdValue, propertyData, GraphEdgeLabels.PROPERTY_IMPL, props); + if (!createRelationRes.equals(TitanOperationStatus.OK)) { + error = createRelationRes; + if (log.isDebugEnabled()) { + log.debug("Failed to create relation from property value {} {} {} {} {}", propertyValue.getUniqueId(), toProperty, propertyId, statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("Before creating relation from property value c", createdValue, toProperty, propertyData.getUniqueId(), statusIs, error); + } + } + if (log.isTraceEnabled()) { + log.trace("After cloning property values {} {} {} {} {}", propertyValueID, ofCI, capabilityInstanceId, statusIs, error); + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java new file mode 100644 index 0000000000..9f00674780 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java @@ -0,0 +1,1196 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + +import org.antlr.misc.Graph; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.fasterxml.jackson.databind.annotation.JsonAppend.Prop; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("capability-operation") +public class CapabilityOperation extends AbstractOperation implements ICapabilityOperation { + + public CapabilityOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(CapabilityOperation.class.getName()); + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + private TitanGenericDao titanGenericDao; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> addCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition, boolean inTransaction) { + + Either<CapabilityDefinition, StorageOperationStatus> result = null; + + try { + + Either<CapabilityData, TitanOperationStatus> addCapStatus = addCapabilityToResource(resourceId, capabilityName, capabilityDefinition); + + if (addCapStatus.isRight()) { + log.debug("Failed to add capability {} [ {} ] to graph", capabilityName, capabilityDefinition); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add Capability", capabilityName, String.valueOf(addCapStatus.right().value())); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addCapStatus.right().value())); + return result; + } else { + CapabilityData capabilityData = addCapStatus.left().value(); + + String capabilityUid = capabilityData.getUniqueId(); + Either<CapabilityDefinition, StorageOperationStatus> capabilityRes = getCapability(capabilityUid, true); + log.debug("After fetching capability {} with uid {}. Status is {}", capabilityName, capabilityUid, capabilityRes); + + if (capabilityRes.isRight()) { + StorageOperationStatus status = capabilityRes.right().value(); + log.debug("Failed to fetch capability {] with uid {}. Status is {}", capabilityName, capabilityUid, status); + result = Either.right(status); + return result; + } + + CapabilityDefinition value = capabilityRes.left().value(); + log.debug("The returned CapabilityDefinition is {}", value); + result = Either.left(value); + + return result; + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus addCapability(TitanVertex metadataVertex, String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition, boolean inTransaction) { + + StorageOperationStatus result = StorageOperationStatus.OK; + try { + + TitanOperationStatus addCapStatus = addCapabilityToResource(metadataVertex, resourceId, capabilityName, capabilityDefinition); + + if (!addCapStatus.equals(TitanOperationStatus.OK)) { + log.debug("Failed to add capability {} [ {} ]", capabilityName, capabilityDefinition); + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError("Add Capability", capabilityName, String.valueOf(addCapStatus)); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(addCapStatus); + } + } finally { + if (false == inTransaction) { + if (result == null || !result.equals(TitanOperationStatus.OK)) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + return result; + } + + private CapabilityDefinition convertCDataToCDefinition(CapabilityData capabilityData) { + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setType(capabilityData.getType()); + + // TODO esofer do something + + return capabilityDefinition; + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String uniqueId) { + + return getCapability(uniqueId, false); + } + + public Either<Map<String, CapabilityDefinition>, StorageOperationStatus> getAllCapabilitiesOfResource(String resourceId, boolean recursively, boolean inTransaction) { + + Map<String, CapabilityDefinition> capabilities = new HashMap<>(); + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> result = null; + Set<String> caseInsensitiveCapabilityNames = new HashSet<>(); + + try { + TitanOperationStatus status = getAllCapabilitiesRecusive(NodeTypeEnum.Resource, resourceId, recursively, capabilities, caseInsensitiveCapabilityNames, inTransaction); + if (!status.equals(TitanOperationStatus.OK)) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + result = Either.left(capabilities); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public TitanOperationStatus getAllCapabilitiesRecusive(NodeTypeEnum nodeType, String resourceId, boolean recursively, Map<String, CapabilityDefinition> capabilities, Set<String> caseInsensitiveCapabilityNames, boolean inTransaction) { + + TitanOperationStatus findStatus; + + if (recursively) { + findStatus = findAllCapabilitiesRecursively(resourceId, capabilities, caseInsensitiveCapabilityNames); + + } else { + findStatus = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + } + if (!findStatus.equals(TitanOperationStatus.OK)) { + return findStatus; + } + + List<String> derivedFromList = new ArrayList<>(); + TitanOperationStatus fillResourceDerivedListFromGraph = fillResourceDerivedListFromGraph(resourceId, derivedFromList); + if (!fillResourceDerivedListFromGraph.equals(TitanOperationStatus.OK)) { + log.debug("fail to find all valid sources of capability. status = {}", fillResourceDerivedListFromGraph.name()); + return fillResourceDerivedListFromGraph; + } + capabilities.forEach((name, capability) -> capability.setCapabilitySources(derivedFromList)); + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus findAllCapabilitiesRecursively(String resourceId, Map<String, CapabilityDefinition> capabilities, Set<String> caseInsensitiveCapabilityNames) { + + TitanOperationStatus resourceCapabilitiesStatus = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + + if (!resourceCapabilitiesStatus.equals(TitanOperationStatus.OK)) { + return resourceCapabilitiesStatus; + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("Failed to find parent capabilities of resource {}. status is {}", resourceId, parentNodesStatus); + BeEcompErrorManager.getInstance().logBeFailedFindParentError("Fetch parent capabilities", resourceId, String.valueOf(parentNodesStatus)); + return parentNodesStatus; + } + } + if (parentNodes.isLeft()) { + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllCapabilitiesRecursively(parentUniqueId, capabilities, caseInsensitiveCapabilityNames); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.debug("Failed to fetch all capabilities of resource {}", parentUniqueId); + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus getCapabilitisOfResourceOnly(String resourceId, Map<String, CapabilityDefinition> capabilities, Set<String> caseInsensitiveCapabilityNames) { + Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> allCapabilitiesRes = getAllCapabilitiesPairs(resourceId); + if (allCapabilitiesRes.isRight()) { + TitanOperationStatus status = allCapabilitiesRes.right().value(); + log.debug("After fetching all capabilities of resource {}. status is {}", resourceId, status); + if (status.equals(TitanOperationStatus.NOT_FOUND)) { + status = TitanOperationStatus.OK; + } + return status; + } + + List<ImmutablePair<CapabilityData, GraphEdge>> capabilityPairs = allCapabilitiesRes.left().value(); + + if (capabilityPairs != null) { + for (ImmutablePair<CapabilityData, GraphEdge> capabilityPair : capabilityPairs) { + CapabilityData capabilityData = capabilityPair.getKey(); + GraphEdge graphEdge = capabilityPair.getValue(); + Map<String, Object> edgeProps = graphEdge.getProperties(); + if (edgeProps != null) { + String capabilityName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (capabilityName == null) { + log.error("Capability name was not found for capability {}", capabilityData.getUniqueId()); + return TitanOperationStatus.INVALID_ELEMENT; + } + Either<CapabilityDefinition, TitanOperationStatus> capabilityDefRes = getCapabilityByCapabilityData(capabilityData); + if (capabilityDefRes.isRight()) { + TitanOperationStatus status = capabilityDefRes.right().value(); + return status; + } + CapabilityDefinition capabilityDefinition = capabilityDefRes.left().value(); + capabilityDefinition.setOwnerId(resourceId); + log.debug("Before adding capability {} with definition {} to result.", capabilityName, capabilityDefinition); + // US631462 + if (caseInsensitiveCapabilityNames.contains(capabilityName.toLowerCase())) { + log.debug("The capability {} was already defined in derived resource (case insensitive). Ignore {} from resource {}", capabilityName, capabilityName, resourceId); + } else { + capabilities.put(capabilityName, capabilityDefinition); + caseInsensitiveCapabilityNames.add(capabilityName.toLowerCase()); + } + } else { + log.debug("Capability name was not found for capability {}", capabilityData.getUniqueId()); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityData.getUniqueId(), String.valueOf(TitanOperationStatus.INVALID_ELEMENT)); + return TitanOperationStatus.INVALID_ELEMENT; + } + + } + } + return TitanOperationStatus.OK; + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String uniqueId, boolean inTransaction) { + + Either<CapabilityDefinition, StorageOperationStatus> result = null; + + try { + Either<CapabilityData, TitanOperationStatus> capabiltyRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, CapabilityData.class); + if (capabiltyRes.isRight()) { + TitanOperationStatus status = capabiltyRes.right().value(); + log.debug("Failed to retrieve capability {} from graph. Status is {}", uniqueId, status); + + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", uniqueId, String.valueOf(status)); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + CapabilityData capabilityData = capabiltyRes.left().value(); + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeRes = getCapabilityTypeOfCapability(uniqueId); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", uniqueId, String.valueOf(status)); + + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, GraphEdgeLabels.CAPABILITY, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentNode.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentNode.right().value())); + } else { + ImmutablePair<ResourceMetadataData, GraphEdge> pair = parentNode.left().value(); + capabilityDefinition.setOwnerId(pair.left.getMetadataDataDefinition().getUniqueId()); + List<String> derivedFromList = new ArrayList<>(); + // derivedFromList.add(pair.left.getMetadataDataDefinition().getName()); + TitanOperationStatus fillResourceDerivedListFromGraph = fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), derivedFromList); + if (fillResourceDerivedListFromGraph.equals(TitanOperationStatus.OK)) { + capabilityDefinition.setCapabilitySources(derivedFromList); + } + } + + Either<List<PropertyDefinition>, TitanOperationStatus> getPropertiesRes = getPropertiesOfCapability(uniqueId, capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + if (getPropertiesRes.isRight() && !getPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Properties of Capability", uniqueId, String.valueOf(status)); + + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + if (getPropertiesRes.isLeft()) { + List<ComponentInstanceProperty> properties = new ArrayList<>(); + for (PropertyDefinition property : getPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private TitanOperationStatus fillResourceDerivedListFromGraph(String uniqueId, List<String> derivedFromList) { + + Either<ResourceMetadataData, TitanOperationStatus> resourceNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, ResourceMetadataData.class); + + if (resourceNode.isRight()) { + TitanOperationStatus parentNodesStatus = resourceNode.right().value(); + if (!parentNodesStatus.equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("Failed to find resource {} . status is {}", uniqueId, parentNodesStatus); + return parentNodesStatus; + } + } + + derivedFromList.add(((ResourceMetadataDataDefinition) resourceNode.left().value().getMetadataDataDefinition()).getToscaResourceName()); + Either<List<ImmutablePair<ResourceMetadataData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (childrenNodes.isRight() && (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND)) { + return childrenNodes.right().value(); + } else if (childrenNodes.isLeft()) { + + List<ImmutablePair<ResourceMetadataData, GraphEdge>> pairList = childrenNodes.left().value(); + for (ImmutablePair<ResourceMetadataData, GraphEdge> pair : pairList) { + return fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), derivedFromList); + } + } + return TitanOperationStatus.OK; + } + + public Either<CapabilityDefinition, TitanOperationStatus> getCapabilityByCapabilityData(CapabilityData capabilityData) { + + Either<CapabilityDefinition, TitanOperationStatus> result; + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + String capabilityUid = capabilityData.getUniqueId(); + Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeRes = getCapabilityTypeOfCapability(capabilityUid); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + return Either.right(status); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either<List<PropertyDefinition>, TitanOperationStatus> capabilityPropertiesRes = getPropertiesOfCapability(capabilityUid, capabilityDefinition.getType()); + if (capabilityPropertiesRes.isRight() && !capabilityPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = capabilityPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + result = Either.right(status); + return result; + } + if (capabilityPropertiesRes.isLeft()) { + List<ComponentInstanceProperty> properties = new ArrayList<>(); + for (PropertyDefinition property : capabilityPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + return result; + } + + public Either<CapabilityDefinition, TitanOperationStatus> getCapabilityByCapabilityData(TitanVertex capabilityDataVertex) { + + Either<CapabilityDefinition, TitanOperationStatus> result; + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + Map<String, Object> props = titanGenericDao.getProperties(capabilityDataVertex); + CapabilityData capabilityData = GraphElementFactory.createElement((String) props.get(GraphPropertiesDictionary.LABEL.getProperty()), GraphElementTypeEnum.Node, props, CapabilityData.class); + capabilityDefinition.setDescription(capabilityData.getDescription()); + capabilityDefinition.setUniqueId(capabilityData.getUniqueId()); + capabilityDefinition.setValidSourceTypes(capabilityData.getValidSourceTypes()); + capabilityDefinition.setMinOccurrences(capabilityData.getMinOccurrences()); + capabilityDefinition.setMaxOccurrences(capabilityData.getMaxOccurrences()); + + String capabilityUid = capabilityData.getUniqueId(); + Either<CapabilityTypeData, TitanOperationStatus> capabilityTypeRes = getCapabilityTypeOfCapability(capabilityUid); + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value(); + log.debug("Failed to retrieve capability type of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + return Either.right(status); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value(); + capabilityDefinition.setType(capabilityTypeData.getCapabilityTypeDataDefinition().getType()); + + Either<List<PropertyDefinition>, TitanOperationStatus> capabilityPropertiesRes = getPropertiesOfCapability(capabilityUid, capabilityDefinition.getType()); + if (capabilityPropertiesRes.isRight() && !capabilityPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = capabilityPropertiesRes.right().value(); + log.debug("Failed to retrieve properties of capability {} . status is {}", capabilityUid, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Capability", capabilityUid, String.valueOf(status)); + + result = Either.right(status); + return result; + } + if (capabilityPropertiesRes.isLeft()) { + List<ComponentInstanceProperty> properties = new ArrayList<>(); + for (PropertyDefinition property : capabilityPropertiesRes.left().value()) { + properties.add(new ComponentInstanceProperty(property, null, null)); + } + capabilityDefinition.setProperties(properties); + } + result = Either.left(capabilityDefinition); + return result; + } + + public Either<List<PropertyDefinition>, TitanOperationStatus> getPropertiesOfCapability(String capabilityUid, String capabilityType) { + log.debug("Before getting properties of capability {} from graph ", capabilityUid); + + List<PropertyDefinition> properties; + Either<List<PropertyDefinition>, TitanOperationStatus> result = null; + Either<Map<String, PropertyDefinition>, TitanOperationStatus> getPropertiesOfCapabilityTypeRes = null; + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> getPropertiesOfCapabilityRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, GraphEdgeLabels.PROPERTY, + NodeTypeEnum.Property, PropertyData.class); + if (getPropertiesOfCapabilityRes.isRight() && !getPropertiesOfCapabilityRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesOfCapabilityRes.right().value(); + log.debug("failed to get properties of capability with id {}. status={}", capabilityUid, status); + result = Either.right(status); + } + if (result == null) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + getPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (getPropertiesOfCapabilityTypeRes.isRight() && !getPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus status = getPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. Status is {}", capabilityType, status); + result = Either.right(status); + } + } + if (result == null) { + result = getPropertiesOfCapabilityTypeRes.isRight() + ? (getPropertiesOfCapabilityRes.isRight() ? Either.right(TitanOperationStatus.NOT_FOUND) + : Either.left(getPropertiesOfCapabilityRes.left().value().stream().map(p -> propertyOperation.convertPropertyDataToPropertyDefinition(p.getKey(), null, capabilityUid)).collect(Collectors.toList()))) + : (getPropertiesOfCapabilityRes.isRight() ? Either.left(getPropertiesOfCapabilityTypeRes.left().value().values().stream().collect(Collectors.toList())) : null); + } + if (result == null) { + Map<String, PropertyDefinition> propertiesOfCapabilityType = getPropertiesOfCapabilityTypeRes.left().value(); + properties = getPropertiesOfCapabilityRes.left().value().stream() + .map(p -> propertyOperation.convertPropertyDataToPropertyDefinition(p.getKey(), (String) p.getRight().getProperties().get(GraphPropertiesDictionary.NAME.getProperty()), capabilityUid)).collect(Collectors.toList()); + properties.stream().forEach(p -> propertiesOfCapabilityType.remove(p.getName())); + properties.addAll(propertiesOfCapabilityType.values()); + result = Either.left(properties); + } + return result; + } + + protected Either<CapabilityTypeData, TitanOperationStatus> getCapabilityTypeOfCapability(String uniqueId) { + + Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> capabilityTypeRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, GraphEdgeLabels.TYPE_OF, NodeTypeEnum.CapabilityType, + CapabilityTypeData.class); + + if (capabilityTypeRes.isRight()) { + TitanOperationStatus status = capabilityTypeRes.right().value();// + log.debug("Cannot find capability type associated with capability {}. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Capability type", NodeTypeEnum.CapabilityType.getName(), uniqueId, String.valueOf(status)); + return Either.right(capabilityTypeRes.right().value()); + } + + CapabilityTypeData capabilityTypeData = capabilityTypeRes.left().value().getKey(); + + return Either.left(capabilityTypeData); + + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String capabilityName, String resourceId) { + return getCapability(UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName)); + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> getCapability(String capabilityName, String resourceId, boolean inTransaction) { + return getCapability(UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName), inTransaction); + } + + @Override + public Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> getAllCapabilitiesPairs(String resourceId) { + + Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> capabilitiesNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.CAPABILITY, + NodeTypeEnum.Capability, CapabilityData.class); + + log.debug("After looking for all capabilities under resource {}. Status is {}", resourceId, capabilitiesNodes); + if (capabilitiesNodes.isRight()) { + TitanOperationStatus status = capabilitiesNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<CapabilityData, GraphEdge>> capabilities = capabilitiesNodes.left().value(); + if (capabilities == null || true == capabilities.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + return Either.left(capabilitiesNodes.left().value()); + } + + private Either<CapabilityData, TitanOperationStatus> addCapabilityToResource(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + log.debug("Going to add capability {} [ {} ] to resource uid {}", capabilityName, capabilityDefinition, resourceId); + + Either<CapabilityData, TitanOperationStatus> createCapRes = createCapability(resourceId, capabilityName, capabilityDefinition); + + log.debug("After creating capability node in graph. status is {}", createCapRes); + if (createCapRes.isRight()) { + TitanOperationStatus status = createCapRes.right().value(); + log.error("Failed to create capability data node in graph. status is {}", status); + return Either.right(status); + } + CapabilityData capabilityData = createCapRes.left().value(); + + String capabilityType = capabilityDefinition.getType(); + + log.debug("Going to associate capability {} to its capabilityType {}", capabilityName, capabilityType); + + Either<GraphRelation, TitanOperationStatus> associateCapabilityTypeRes = associateCapabilityToCapabilityType(capabilityData, capabilityType); + log.debug("After associating capability {} to its capabilityType {}. status is {}", capabilityName, capabilityType, associateCapabilityTypeRes); + if (associateCapabilityTypeRes.isRight()) { + TitanOperationStatus status = associateCapabilityTypeRes.right().value(); + log.error("Failed to associate capability {} to its capabilityType {} in graph. status is {} ", capabilityName, capabilityType, status); + + return Either.right(status); + } + List<ComponentInstanceProperty> ciProperties = capabilityDefinition.getProperties(); + if (ciProperties != null && !ciProperties.isEmpty()) { + List<PropertyDefinition> properties = ciProperties.stream().map(prop -> new PropertyDefinition(prop)).collect(Collectors.toList()); + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesRes = addPropertiesToCapability(capabilityData, capabilityType, properties); + if (addPropertiesRes.isRight()) { + TitanOperationStatus operationStatus = addPropertiesRes.right().value(); + return Either.right(operationStatus); + } + } + + Either<GraphRelation, TitanOperationStatus> associateResourceRes = associateResourceToCapability(resourceId, capabilityName, capabilityData); + if (associateResourceRes.isRight()) { + TitanOperationStatus status = associateResourceRes.right().value(); + log.error("Failed to associate resource " + resourceId + " to capability " + capabilityData + ". status is " + status); + return Either.right(status); + } + + return Either.left(capabilityData); + + } + + private TitanOperationStatus addCapabilityToResource(TitanVertex metadataVertex, String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + log.debug("Going to add capability {} [ {} ] to resource uid {}", capabilityName, capabilityDefinition, resourceId); + + Either<TitanVertex, TitanOperationStatus> createCapRes = createCapabilityVertex(resourceId, capabilityName, capabilityDefinition); + + log.debug("After creating capability node in graph. status is {}", createCapRes); + if (createCapRes.isRight()) { + TitanOperationStatus status = createCapRes.right().value(); + log.error("Failed to create capability data node in graph. status is {}", status); + return status; + } + TitanVertex capabilityVertex = createCapRes.left().value(); + + String capabilityType = capabilityDefinition.getType(); + + log.debug("Going to associate capability {} to its capabilityType {}", capabilityName, capabilityType); + + TitanOperationStatus associateCapabilityTypeRes = associateCapabilityToCapabilityType(capabilityVertex, capabilityType); + log.debug("After associating capability {} to its capabilityType {}. status is {}", capabilityName, capabilityType, associateCapabilityTypeRes); + if (!associateCapabilityTypeRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate capability {} to its capabilityType {} in graph. status is {} ", capabilityName, capabilityType, associateCapabilityTypeRes); + return associateCapabilityTypeRes; + } + List<ComponentInstanceProperty> ciProperties = capabilityDefinition.getProperties(); + if (ciProperties != null && !ciProperties.isEmpty()) { + String capabiltyId = (String) titanGenericDao.getProperty(capabilityVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + List<PropertyDefinition> properties = ciProperties.stream().map(prop -> new PropertyDefinition(prop)).collect(Collectors.toList()); + TitanOperationStatus addPropertiesRes = addPropertiesToCapability(capabilityVertex, capabilityType, properties, capabiltyId); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + return addPropertiesRes; + } + } + + TitanOperationStatus associateResourceRes = associateResourceToCapability(resourceId, capabilityName, capabilityVertex, metadataVertex); + if (!associateResourceRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource{} to capability {}. status is {} ", resourceId, capabilityName, associateResourceRes); + } + + return associateResourceRes; + + } + + private Either<GraphRelation, TitanOperationStatus> associateCapabilityToCapabilityType(CapabilityData capabilityData, String capabilityType) { + UniqueIdData capabilityTypeIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, UniqueIdBuilder.buildCapabilityTypeUid(capabilityType)); + log.debug("Before associating {} to capability type {}.", capabilityData, capabilityType); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(capabilityData, capabilityTypeIdData, GraphEdgeLabels.TYPE_OF, null); + log.debug("After associating {} to capability type {}. status is {}", capabilityData, capabilityType, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate capability {} to capability type {} in graph. Status is {}",capabilityData, capabilityTypeIdData, operationStatus); + return Either.right(operationStatus); + } + return Either.left(createRelResult.left().value()); + + } + + private TitanOperationStatus associateCapabilityToCapabilityType(TitanVertex capabilityVertex, String capabilityType) { + + UniqueIdData capabilityTypeIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, UniqueIdBuilder.buildCapabilityTypeUid(capabilityType)); + + log.debug("Before associating {} to capability type {}.", capabilityVertex, capabilityType); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(capabilityVertex, capabilityTypeIdData, GraphEdgeLabels.TYPE_OF, null); + log.trace("After associating {} to capability type {}. status is {}", capabilityVertex, capabilityType, createRelResult); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate capability {} to capability type {} in graph. status is {}", capabilityVertex, capabilityTypeIdData, createRelResult); + } + return createRelResult; + } + + private Either<GraphRelation, TitanOperationStatus> associateResourceToCapability(String resourceId, String capabilityName, CapabilityData capabilityData) { + + UniqueIdData resourceIdData = new UniqueIdData(NodeTypeEnum.Resource, resourceId); + + log.debug("Before associating resource {} to capability {}.", resourceId, capabilityData); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceIdData, capabilityData, GraphEdgeLabels.CAPABILITY, props); + log.debug("After associating resource {} to capability {}. Status is {}", resourceId, capabilityData, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource {} to capability {} in graph. Status is {}", resourceId, capabilityData, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createRelResult.left().value()); + + } + + private TitanOperationStatus associateResourceToCapability(String resourceId, String capabilityName, TitanVertex capabilityVertex, TitanVertex resourceVertex) { + + log.debug("Before associating resource {} to capability {}.", resourceId, capabilityName); + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(resourceVertex, capabilityVertex, GraphEdgeLabels.CAPABILITY, props); + log.debug("After associating resource {} to capability {}. status is {}", resourceId, capabilityName, createRelResult); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to capability {} in graph. status is {}", resourceId, capabilityName, createRelResult); + } + + return createRelResult; + + } + + /** + * + * create capability node in the graph + * + * @param resourceId + * @param capabilityName + * @param capabilityDefinition + * @return + */ + private Either<CapabilityData, TitanOperationStatus> createCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + CapabilityData capabilityData = new CapabilityData(); + String uid = UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName); + capabilityData.setUniqueId(uid); + Long creationTime = System.currentTimeMillis(); + capabilityData.setCreationTime(creationTime); + capabilityData.setModificationTime(creationTime); + capabilityData.setValidSourceTypes(capabilityDefinition.getValidSourceTypes()); + capabilityData.setMinOccurrences(capabilityDefinition.getMinOccurrences()); + capabilityData.setMaxOccurrences(capabilityDefinition.getMaxOccurrences()); + capabilityData.setDescription(capabilityDefinition.getDescription()); + + Either<CapabilityData, TitanOperationStatus> createNode = titanGenericDao.createNode(capabilityData, CapabilityData.class); + + log.debug("After creating capability node in the graph. status is {}", createNode); + + return createNode; + } + + private Either<TitanVertex, TitanOperationStatus> createCapabilityVertex(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + CapabilityData capabilityData = new CapabilityData(); + String uid = UniqueIdBuilder.buildCapabilityUid(resourceId, capabilityName); + capabilityData.setUniqueId(uid); + Long creationTime = System.currentTimeMillis(); + capabilityData.setCreationTime(creationTime); + capabilityData.setModificationTime(creationTime); + capabilityData.setValidSourceTypes(capabilityDefinition.getValidSourceTypes()); + capabilityData.setMinOccurrences(capabilityDefinition.getMinOccurrences()); + capabilityData.setMaxOccurrences(capabilityDefinition.getMaxOccurrences()); + capabilityData.setDescription(capabilityDefinition.getDescription()); + + Either<TitanVertex, TitanOperationStatus> createNode = titanGenericDao.createNode(capabilityData); + + log.debug("After creating capability node in the graph. status is {}", createNode); + + return createNode; + } + + @Override + public Either<CapabilityDefinition, StorageOperationStatus> addCapability(String resourceId, String capabilityName, CapabilityDefinition capabilityDefinition) { + + return addCapability(resourceId, capabilityName, capabilityDefinition, false); + + } + + public StorageOperationStatus deleteCapabilityFromGraph(String capabilityUid) { + + TitanOperationStatus resultStatus = null; + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deletePropertiesStatus = deletePropertiesOfCapability(capabilityUid); + + if (deletePropertiesStatus.isRight() && !deletePropertiesStatus.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + resultStatus = deletePropertiesStatus.right().value(); + } + if (resultStatus == null) { + log.debug("Before deleting capability from graph {}", capabilityUid); + Either<CapabilityData, TitanOperationStatus> deleteNodeStatus = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, CapabilityData.class); + if (deleteNodeStatus.isRight()) { + resultStatus = deleteNodeStatus.right().value(); + } + } + if (resultStatus != null) { + log.debug("failed to delete capability with id {}. status={}", capabilityUid, resultStatus); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete capability", capabilityUid, String.valueOf(resultStatus)); + return DaoStatusConverter.convertTitanStatusToStorageStatus(resultStatus); + } + return StorageOperationStatus.OK; + } + + public Either<Map<String, CapabilityDefinition>, StorageOperationStatus> deleteAllCapabilities(String resourceId, boolean inTransaction) { + + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> result = null; + try { + + Either<Map<String, CapabilityDefinition>, TitanOperationStatus> deleteAllRes = deleteAllCapabilitiesOfResource(resourceId); + if (deleteAllRes.isRight()) { + TitanOperationStatus status = deleteAllRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to delete capabilities of resource {}. Status is {}", resourceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map<String, CapabilityDefinition> value = deleteAllRes.left().value(); + result = Either.left(value); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + public Either<Map<String, CapabilityDefinition>, StorageOperationStatus> deleteAllCapabilities(String resourceId) { + + return deleteAllCapabilities(resourceId, false); + + } + + private Either<Map<String, CapabilityDefinition>, TitanOperationStatus> deleteAllCapabilitiesOfResource(String resourceId) { + TitanOperationStatus resultStatus = null; + Map<String, CapabilityDefinition> capabilities = new HashMap<>(); + Set<String> caseInsensitiveCapabilityNames = new HashSet<>(); + TitanOperationStatus capabilitisRes = getCapabilitisOfResourceOnly(resourceId, capabilities, caseInsensitiveCapabilityNames); + if (capabilitisRes != TitanOperationStatus.OK) { + return Either.right(capabilitisRes); + } + + if (capabilities.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + for (Entry<String, CapabilityDefinition> entry : capabilities.entrySet()) { + CapabilityDefinition capabilityDefinition = entry.getValue(); + String capabilityUid = capabilityDefinition.getUniqueId(); + + log.debug("Before deleting properties of capability {} from graph", capabilityUid); + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deletePropertiesStatus = deletePropertiesOfCapability(capabilityUid); + if (deletePropertiesStatus.isRight() && !deletePropertiesStatus.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + resultStatus = deletePropertiesStatus.right().value(); + } + if (resultStatus == null) { + Either<CapabilityData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, CapabilityData.class); + if (deleteNodeRes.isRight()) { + resultStatus = deleteNodeRes.right().value(); + } + } + if (resultStatus != null) { + log.debug("Failed to delete capability {} of resource {}", capabilityUid, resourceId); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError("Delete capability", capabilityUid, String.valueOf(resultStatus)); + return Either.right(resultStatus); + } + } + + return Either.left(capabilities); + + } + + public Map<String, List<CapabilityDefinition>> convertCapabilityMap(Map<String, CapabilityDefinition> capabilityMap, String ownerId, String ownerName) { + + Map<String, List<CapabilityDefinition>> typeToRequirementMap = new HashMap<>(); + capabilityMap.forEach((capabilityName, capability) -> { + capability.setName(capabilityName); + if (typeToRequirementMap.containsKey(capability.getType())) { + typeToRequirementMap.get(capability.getType()).add(capability); + } else { + List<CapabilityDefinition> list = new ArrayList<>(); + list.add(capability); + typeToRequirementMap.put(capability.getType(), list); + } + }); + return typeToRequirementMap; + } + + public TitanOperationStatus getCapabilitySourcesList(String resourceId, List<String> derivedFromList) { + Map<String, Object> propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId); + Either<List<ResourceMetadataData>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + if (getResponse.isRight()) { + return getResponse.right().value(); + } else { + String toscaResourceName = ((ResourceMetadataDataDefinition) getResponse.left().value().get(0).getMetadataDataDefinition()).getToscaResourceName(); + derivedFromList.add(toscaResourceName); + } + + Either<List<ImmutablePair<ResourceMetadataData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + while (childrenNodes.isLeft()) { + + List<ImmutablePair<ResourceMetadataData, GraphEdge>> pairList = childrenNodes.left().value(); + ResourceMetadataData left = pairList.get(0).left; + derivedFromList.add(((ResourceMetadataDataDefinition) left.getMetadataDataDefinition()).getToscaResourceName()); + String id = left.getMetadataDataDefinition().getUniqueId(); + childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), id, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + } + return TitanOperationStatus.OK; + } + + private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapability(CapabilityData capabilityData, String capabilityType, List<PropertyDefinition> properties) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus operationStatus = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type " + capabilityType + " from graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Map<String, PropertyDefinition> propertiesOfCapabilityType = null; + + if (allPropertiesOfCapabilityTypeRes.isLeft() && allPropertiesOfCapabilityTypeRes.left() != null && !allPropertiesOfCapabilityTypeRes.left().value().isEmpty()) { + + propertiesOfCapabilityType = allPropertiesOfCapabilityTypeRes.left().value(); + Either<List<PropertyDefinition>, TitanOperationStatus> validateAndReducePropertiesRes = validatePropertyUniqueness(propertiesOfCapabilityType, properties); + if (validateAndReducePropertiesRes.isRight()) { + TitanOperationStatus operationStatus = validateAndReducePropertiesRes.right().value(); + log.error("Failed to add properties to capability {} in graph. Status is {}", capabilityData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + } + + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapabilityRes = propertyOperation.addPropertiesToElementType(capabilityData.getUniqueId(), NodeTypeEnum.Capability, properties); + if (addPropertiesToCapabilityRes.isRight()) { + TitanOperationStatus operationStatus = addPropertiesToCapabilityRes.right().value(); + log.error("Failed to add properties to capability {} in graph. Status is {}", capabilityData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + return Either.left(addPropertiesToCapabilityRes.left().value()); + } + + private TitanOperationStatus addPropertiesToCapability(TitanVertex capabilityVertex, String capabilityType, List<PropertyDefinition> properties, String uniqueId) { + String capabilityTypeUid = UniqueIdBuilder.buildCapabilityTypeUid(capabilityType); + Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeUid); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + TitanOperationStatus operationStatus = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. status is {}", capabilityType, operationStatus); + return operationStatus; + } + Map<String, PropertyDefinition> propertiesOfCapabilityType = null; + + if (allPropertiesOfCapabilityTypeRes.isLeft() && allPropertiesOfCapabilityTypeRes.left() != null && !allPropertiesOfCapabilityTypeRes.left().value().isEmpty()) { + + propertiesOfCapabilityType = allPropertiesOfCapabilityTypeRes.left().value(); + Either<List<PropertyDefinition>, TitanOperationStatus> validateAndReducePropertiesRes = validatePropertyUniqueness(propertiesOfCapabilityType, properties); + if (validateAndReducePropertiesRes.isRight()) { + TitanOperationStatus operationStatus = validateAndReducePropertiesRes.right().value(); + log.error("Failed to add properties to capability {} in graph. status is {}", capabilityVertex, operationStatus); + return operationStatus; + } + } + + String capabiltyId = (String) titanGenericDao.getProperty(capabilityVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + TitanOperationStatus addPropertiesToCapabilityRes = propertyOperation.addPropertiesToElementType(capabilityVertex, capabiltyId, NodeTypeEnum.Capability, properties); + if (!addPropertiesToCapabilityRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to add properties to capability {} in graph. status is {}", capabiltyId, addPropertiesToCapabilityRes); + } + return addPropertiesToCapabilityRes; + } + + public Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertyUniqueness(Map<String, PropertyDefinition> propertiesOfCapabilityType, List<PropertyDefinition> properties) { + Either<List<PropertyDefinition>, TitanOperationStatus> result = Either.left(properties); + + for (PropertyDefinition property : properties) { + String propertyName = property.getName(); + String propertyType = property.getType(); + PropertyDefinition defaultProperty = null; + + if (propertiesOfCapabilityType.containsKey(propertyName)) { + defaultProperty = propertiesOfCapabilityType.get(propertyName); + if (propertyType != null && defaultProperty.getType() != null && !defaultProperty.getType().equals(propertyType)) { + log.error(" Property with name {} and different type already exists.", propertyName); + result = Either.right(TitanOperationStatus.PROPERTY_NAME_ALREADY_EXISTS); + } else { + property.setType(defaultProperty.getType()); + String innerType = defaultProperty.getSchema() == null ? null : defaultProperty.getSchema().getProperty() == null ? null : defaultProperty.getSchema().getProperty().getType(); + + if (property.getSchema() != null && property.getSchema().getProperty() != null) { + property.getSchema().getProperty().setType(innerType); + } + } + } + } + return result; + } + + public StorageOperationStatus validateUpdateCapabilityProperty(PropertyDefinition property) { + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return DaoStatusConverter.convertTitanStatusToStorageStatus(allDataTypes.right().value()); + } + return propertyOperation.validateAndUpdateProperty(property, allDataTypes.left().value()); + } + + public StorageOperationStatus validateCapabilityProperties(List<PropertyDefinition> properties) { + StorageOperationStatus result = StorageOperationStatus.OK; + for (PropertyDefinition property : properties) { + result = validateUpdateCapabilityProperty(property); + if (!result.equals(StorageOperationStatus.OK)) + break; + } + return result; + } + + public Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deletePropertiesOfCapability(String capabilityUid) { + log.debug("Before deleting properties of capability {} from graph ", capabilityUid); + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deletePropertiesStatus = titanGenericDao.deleteChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capabilityUid, GraphEdgeLabels.PROPERTY, + NodeTypeEnum.Property, PropertyData.class); + if (deletePropertiesStatus.isRight()) { + TitanOperationStatus status = deletePropertiesStatus.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to delete properties of capability with id {}. status={}", capabilityUid, status); + } else { + log.debug("The Capability with id {} have no Properties. status={}", capabilityUid, status); + } + return Either.right(status); + } + return Either.left(deletePropertiesStatus.left().value()); + } + + @Override + public Either<Map<String, PropertyData>, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, String capabilityType, List<PropertyDefinition> newProperties) { + return updatePropertiesOfCapability(uniqueId, capabilityType, newProperties, false); + } + + @Override + public Either<Map<String, PropertyData>, StorageOperationStatus> updatePropertiesOfCapability(String uniqueId, String capabilityType, List<PropertyDefinition> newProperties, boolean inTransaction) { + + Either<Map<String, PropertyData>, StorageOperationStatus> result = null; + try { + Either<CapabilityData, TitanOperationStatus> capabiltyRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), uniqueId, CapabilityData.class); + if (capabiltyRes.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(capabiltyRes.right().value())); + } + CapabilityData capabilityData = capabiltyRes.left().value(); + if (result == null) { + StorageOperationStatus propertiesValidationRes = validateCapabilityProperties(newProperties); + if (!propertiesValidationRes.equals(StorageOperationStatus.OK)) { + result = Either.right(propertiesValidationRes); + } + } + if (result == null) { + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deletePropertiesRes = deletePropertiesOfCapability(uniqueId); + if (deletePropertiesRes.isRight() && !deletePropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deletePropertiesRes.right().value())); + } + } + if (result == null) { + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesRes = addPropertiesToCapability(capabilityData, capabilityType, newProperties); + if (addPropertiesRes.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesRes.right().value())); + } else { + result = Either.left(addPropertiesRes.left().value()); + } + } + if (result.isRight()) { + log.debug("Failed to update properties of capability {}. Status is {}", uniqueId, result); + } + return result; + } finally { + if (!inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + public Either<CapabilityData, TitanOperationStatus> getCapabilityRelatedToResourceInstance(String resourceInstanceId, String capabilityUid) { + TitanOperationStatus error = null; + CapabilityData capability = null; + Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> getCapabilitiesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + if (getCapabilitiesRes.isRight()) { + error = getCapabilitiesRes.right().value(); + log.debug("Failed to retrieve capabilities for resource instance {}. Status is {}", resourceInstanceId, error); + } else { + List<ImmutablePair<CapabilityData, GraphEdge>> capabilityPairsList = getCapabilitiesRes.left().value(); + List<CapabilityData> capabilityPair = capabilityPairsList.stream().filter(pair -> pair.getLeft().getUniqueId().equals(capabilityUid)).map(pair -> pair.getLeft()).collect(Collectors.toList()); + if (capabilityPair.isEmpty()) { + error = TitanOperationStatus.NOT_FOUND; + log.debug("Failed to retrieve capability {} for resource instance {}. Status is {}", capabilityUid, resourceInstanceId, error); + } else { + capability = capabilityPair.get(0); + } + } + if (error == null) { + return Either.left(capability); + } + return Either.right(error); + } + + public Either<Map<String, PropertyDefinition>, TitanOperationStatus> getAllCapabilityTypePropertiesFromAllDerivedFrom(String firstParentType) { + Map<String, PropertyDefinition> allProperies = new HashMap<>(); + return getCapabilityTypePropertiesFromDerivedFromRecursively(firstParentType, allProperies); + } + + private Either<Map<String, PropertyDefinition>, TitanOperationStatus> getCapabilityTypePropertiesFromDerivedFromRecursively(String nextParentType, Map<String, PropertyDefinition> allProperies) { + TitanOperationStatus error; + Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), nextParentType, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + error = childrenNodes.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", nextParentType, error); + return Either.right(error); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(allProperies); + } + } else { + + Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesOfCapabilityTypeRes = propertyOperation.findPropertiesOfNode(NodeTypeEnum.CapabilityType, nextParentType); + if (allPropertiesOfCapabilityTypeRes.isRight() && !allPropertiesOfCapabilityTypeRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = allPropertiesOfCapabilityTypeRes.right().value(); + log.error("Failed to retrieve properties for capability type {} from graph. Status is {}", nextParentType, error); + return Either.right(error); + } else if (allPropertiesOfCapabilityTypeRes.isLeft()) { + if (allProperies.isEmpty()) { + allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value()); + } else { + allProperies.putAll(allPropertiesOfCapabilityTypeRes.left().value().entrySet().stream().filter(e -> !allProperies.containsKey(e.getKey())).collect(Collectors.toMap(Entry::getKey, Entry::getValue))); + } + } + return getCapabilityTypePropertiesFromDerivedFromRecursively(childrenNodes.left().value().get(0).getLeft().getUniqueId(), allProperies); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java new file mode 100644 index 0000000000..985399cb65 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("capability-type-operation") +public class CapabilityTypeOperation extends AbstractOperation implements ICapabilityTypeOperation { + @Autowired + private PropertyOperation propertyOperation; + @Autowired + private CapabilityOperation capabilityOperation; + + public CapabilityTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(CapabilityTypeOperation.class.getName()); + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition, boolean inTransaction) { + + Either<CapabilityTypeDefinition, StorageOperationStatus> result = null; + + try { + Either<CapabilityTypeDefinition, TitanOperationStatus> validationRes = validateUpdateProperties( + capabilityTypeDefinition); + if (validationRes.isRight()) { + log.error("One or all properties of capability type {} not valid. status is {}", + capabilityTypeDefinition, validationRes.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(validationRes.right().value())); + return result; + } + Either<CapabilityTypeData, TitanOperationStatus> eitherStatus = addCapabilityTypeToGraph( + capabilityTypeDefinition); + + if (eitherStatus.isRight()) { + log.error("Failed to add capability {} to Graph. status is {}", capabilityTypeDefinition, + eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + CapabilityTypeData capabilityTypeData = eitherStatus.left().value(); + + CapabilityTypeDefinition capabilityTypeDefResult = convertCTDataToCTDefinition(capabilityTypeData); + log.debug("The returned CapabilityTypeDefinition is {}", capabilityTypeDefResult); + result = Either.left(capabilityTypeDefResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private Either<CapabilityTypeDefinition, TitanOperationStatus> validateUpdateProperties( + CapabilityTypeDefinition capabilityTypeDefinition) { + TitanOperationStatus error = null; + if (capabilityTypeDefinition.getProperties() != null && !capabilityTypeDefinition.getProperties().isEmpty() + && capabilityTypeDefinition.getDerivedFrom() != null) { + Either<Map<String, PropertyDefinition>, TitanOperationStatus> allPropertiesRes = capabilityOperation + .getAllCapabilityTypePropertiesFromAllDerivedFrom(capabilityTypeDefinition.getDerivedFrom()); + if (allPropertiesRes.isRight() + && !allPropertiesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = allPropertiesRes.right().value(); + log.debug("Couldn't fetch derived from property nodes for capability type {}, error: {}", + capabilityTypeDefinition.getType(), error); + } + if (error == null && !allPropertiesRes.left().value().isEmpty()) { + Map<String, PropertyDefinition> derivedFromProperties = allPropertiesRes.left().value(); + capabilityTypeDefinition.getProperties().entrySet().stream() + .filter(e -> derivedFromProperties.containsKey(e.getKey()) && e.getValue().getType() == null) + .forEach(e -> e.getValue().setType(derivedFromProperties.get(e.getKey()).getType())); + + Either<List<PropertyDefinition>, TitanOperationStatus> validatePropertiesRes = capabilityOperation + .validatePropertyUniqueness(allPropertiesRes.left().value(), capabilityTypeDefinition + .getProperties().values().stream().collect(Collectors.toList())); + if (validatePropertiesRes.isRight()) { + error = validatePropertiesRes.right().value(); + } + } + } + if (error == null) { + return Either.left(capabilityTypeDefinition); + } + return Either.right(error); + } + + /** + * + * convert between graph Node object to Java object + * + * @param capabilityTypeData + * @return + */ + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is {}", capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + /** + * + * Add capability type to graph. + * + * 1. Add capability type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per + * property & if exists) + * + * @param capabilityTypeDefinition + * @return + */ + private Either<CapabilityTypeData, TitanOperationStatus> addCapabilityTypeToGraph( + CapabilityTypeDefinition capabilityTypeDefinition) { + + log.debug("Got capability type {}", capabilityTypeDefinition); + + String ctUniqueId = UniqueIdBuilder.buildCapabilityTypeUid(capabilityTypeDefinition.getType()); + // capabilityTypeDefinition.setUniqueId(ctUniqueId); + + CapabilityTypeData capabilityTypeData = buildCapabilityTypeData(capabilityTypeDefinition, ctUniqueId); + + log.debug("Before adding capability type to graph. capabilityTypeData = {}", capabilityTypeData); + Either<CapabilityTypeData, TitanOperationStatus> createCTResult = titanGenericDao.createNode(capabilityTypeData, + CapabilityTypeData.class); + log.debug("After adding capability type to graph. status is = {}", createCTResult); + + if (createCTResult.isRight()) { + TitanOperationStatus operationStatus = createCTResult.right().value(); + log.error("Failed to capability type " + capabilityTypeDefinition.getType() + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + CapabilityTypeData resultCTD = createCTResult.left().value(); + Map<String, PropertyDefinition> propertiesMap = capabilityTypeDefinition.getProperties(); + Collection<PropertyDefinition> properties = propertiesMap != null ? propertiesMap.values() : null; + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.CapabilityType, propertiesMap); + if (addPropertiesToCapablityType.isRight()) { + log.error( + "Failed add properties " + propertiesMap + " to capability " + capabilityTypeDefinition.getType()); + return Either.right(addPropertiesToCapablityType.right().value()); + } + + String derivedFrom = capabilityTypeDefinition.getDerivedFrom(); + if (derivedFrom != null) { + log.debug( + "Before creating relation between capability type " + ctUniqueId + " to its parent " + derivedFrom); + UniqueIdData from = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId); + UniqueIdData to = new UniqueIdData(NodeTypeEnum.CapabilityType, derivedFrom); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, + GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between capability type {} to its parent {}. Status is {}", ctUniqueId, derivedFrom, createRelation); + if (createRelation.isRight()) { + return Either.right(createRelation.right().value()); + } + } + + return Either.left(createCTResult.left().value()); + + } + + private CapabilityTypeData buildCapabilityTypeData(CapabilityTypeDefinition capabilityTypeDefinition, + String ctUniqueId) { + + CapabilityTypeData capabilityTypeData = new CapabilityTypeData(capabilityTypeDefinition); + + capabilityTypeData.getCapabilityTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = capabilityTypeData.getCapabilityTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + capabilityTypeData.getCapabilityTypeDataDefinition().setCreationTime(creationDate); + capabilityTypeData.getCapabilityTypeDataDefinition().setModificationTime(creationDate); + return capabilityTypeData; + } + + @Override + public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId, + boolean inTransaction) { + + Either<CapabilityTypeDefinition, StorageOperationStatus> result = null; + try { + + Either<CapabilityTypeDefinition, TitanOperationStatus> ctResult = this.getCapabilityTypeByUid(uniqueId); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type {}. Status is {}", uniqueId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + /** + * Build Capability type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either<CapabilityTypeDefinition, TitanOperationStatus> getCapabilityTypeByUid(String uniqueId) { + + Either<CapabilityTypeDefinition, TitanOperationStatus> result = null; + + Either<CapabilityTypeData, TitanOperationStatus> capabilityTypesRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, CapabilityTypeData.class); + + if (capabilityTypesRes.isRight()) { + TitanOperationStatus status = capabilityTypesRes.right().value(); + log.debug("Capability type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + CapabilityTypeData ctData = capabilityTypesRes.left().value(); + CapabilityTypeDefinition capabilityTypeDefinition = new CapabilityTypeDefinition( + ctData.getCapabilityTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, capabilityTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability type " + uniqueId); + return Either.right(propertiesStatus); + } + + Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), uniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + log.debug("After retrieving DERIVED_FROM node of {}. Status is {}", uniqueId, parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent capability of capability type {}. Status is {}", uniqueId, titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair<CapabilityTypeData, GraphEdge> immutablePair = parentNode.left().value(); + CapabilityTypeData parentCT = immutablePair.getKey(); + capabilityTypeDefinition.setDerivedFrom(parentCT.getCapabilityTypeDataDefinition().getType()); + } + result = Either.left(capabilityTypeDefinition); + + return result; + } + + private TitanOperationStatus fillProperties(String uniqueId, CapabilityTypeDefinition capabilityTypeDefinition) { + + Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = propertyOperation + .findPropertiesOfNode(NodeTypeEnum.CapabilityType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex {}. Status is {}", uniqueId, titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value(); + capabilityTypeDefinition.setProperties(properties); + return TitanOperationStatus.OK; + } + } + + public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, + String parentCandidateType) { + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); + Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao + .getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + String childUniqueId = getResponse.left().value().get(0).getUniqueId(); + Set<String> travelledTypes = new HashSet<>(); + do { + travelledTypes.add(childUniqueId); + Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, + titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + if (derivedFromUniqueId.equals(parentCandidateType)) { + log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, + parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + } while (!travelledTypes.contains(childUniqueId)); + // this stop condition should never be used, if we use it, we have an + // illegal cycle in graph - "derived from" hierarchy cannot be cycled. + // It's here just to avoid infinite loop in case we have such cycle. + log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + /** + * FOR TEST ONLY + * + * @param propertyOperation + */ + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + @Override + public Either<CapabilityTypeDefinition, StorageOperationStatus> addCapabilityType( + CapabilityTypeDefinition capabilityTypeDefinition) { + + return addCapabilityType(capabilityTypeDefinition, false); + } + + @Override + public Either<CapabilityTypeDefinition, StorageOperationStatus> getCapabilityType(String uniqueId) { + return getCapabilityType(uniqueId, false); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java new file mode 100644 index 0000000000..cb85888780 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java @@ -0,0 +1,5852 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GetInputValueInfo; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.IComponentInstanceConnectedElement; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.AttributeValueData; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.InputsData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RelationshipInstData; +import org.openecomp.sdc.be.resources.data.RelationshipTypeData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import com.thinkaurelius.titan.core.TitanVertexQuery; + +import fj.data.Either; + +@org.springframework.stereotype.Component("component-instance-operation") +public class ComponentInstanceOperation extends AbstractOperation implements IComponentInstanceOperation { + + public ComponentInstanceOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ComponentInstanceOperation.class.getName()); + + @Autowired + private ResourceOperation resourceOperation; + + @Autowired + private ServiceOperation serviceOperation; + + @Autowired + CapabilityOperation capabilityOperation; + + @Autowired + private CapabilityInstanceOperation capabilityInstanceOperation; + + @Autowired + private CapabilityTypeOperation capabilityTypeOperation; + + @Autowired + private RequirementOperation requirementOperation; + + @Autowired + private ArtifactOperation artifactOperation; + + @Autowired + TitanGenericDao titanGenericDao; + + @Autowired + PropertyOperation propertyOperation; + + @Autowired + InputsOperation inputOperation; + + @Autowired + private IAttributeOperation attributeOperation; + + @Autowired + private ApplicationDataTypeCache dataTypeCache; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> createComponentInstance(String parentComponentId, NodeTypeEnum nodeType, String instanceNumber, ComponentInstance componentInstance, NodeTypeEnum compInstNodeType, boolean inTransaction) { + + return createComponentInstance(parentComponentId, nodeType, instanceNumber, true, componentInstance, compInstNodeType, false, inTransaction); + + } + + private Either<ComponentInstance, StorageOperationStatus> createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLocgicalName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, boolean inTransaction) { + Either<ComponentInstance, StorageOperationStatus> result = null; + + try { + + Either<ComponentInstance, TitanOperationStatus> addRes = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLocgicalName, componentInstance, compInstNodeType, allowDeleted); + if (addRes.isRight()) { + TitanOperationStatus status = addRes.right().value(); + log.error("Failed to add resource instance {} to service {}. Status is {}", componentInstance, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = addRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + private Either<TitanVertex, StorageOperationStatus> createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLocgicalName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, boolean inTransaction, TitanVertex metadataVertex) { + Either<TitanVertex, StorageOperationStatus> result = null; + + try { + + Either<TitanVertex, TitanOperationStatus> addRes = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLocgicalName, componentInstance, compInstNodeType, allowDeleted, metadataVertex); + if (addRes.isRight()) { + TitanOperationStatus status = addRes.right().value(); + log.error("Failed to add resource instance {} to service {}. status is {}", componentInstance, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + TitanVertex value = addRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> createComponentInstance(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, ComponentInstance componentInstance, NodeTypeEnum instNodeType) { + + return createComponentInstance(containerComponentId, containerNodeType, instanceNumber, componentInstance, instNodeType, false); + + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> deleteComponentInstance(NodeTypeEnum containerNodeType, String containerComponentId, String resourceInstUid, boolean inTransaction) { + + Either<ComponentInstance, StorageOperationStatus> result = null; + + try { + + Either<ComponentInstance, TitanOperationStatus> deleteRes = removeComponentInstanceFromComponent(containerNodeType, containerComponentId, resourceInstUid); + + if (deleteRes.isRight()) { + TitanOperationStatus status = deleteRes.right().value(); + log.error("Failed to remove resource instance {} from component {}. Status is {}", resourceInstUid, containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = deleteRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> deleteComponentInstance(NodeTypeEnum containerNodeType, String containerComponentId, String resourceInstUid) { + + return deleteComponentInstance(containerNodeType, containerComponentId, resourceInstUid, false); + } + + private <T> void commitOrRollback(Either<T, StorageOperationStatus> result) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + @Override + public Either<Boolean, StorageOperationStatus> validateParent(String parentId, String uniqId, boolean inTransaction) { + + Either<Boolean, StorageOperationStatus> result = null; + Either<Boolean, TitanOperationStatus> updateRes = validateParentonGraph(parentId, uniqId, inTransaction); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to find resource instance name {}. Status is {}", uniqId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Boolean value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } + + public Either<Boolean, TitanOperationStatus> validateParentonGraph(String parentId, String uniqId, boolean inTransaction) { + + Either<TitanGraph, TitanOperationStatus> graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.debug("Failed to retrieve graph. status is {}", graphRes); + return Either.right(graphRes.right().value()); + } + TitanGraph titanGraph = graphRes.left().value(); + try { + Iterable<TitanVertex> vertices = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), uniqId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + TitanVertex vertex = vertices.iterator().next(); + + TitanVertexQuery query = vertex.query(); + query = query.labels(GraphEdgeLabels.RESOURCE_INST.getProperty()).direction(Direction.IN); + Iterable<Vertex> verts = query.vertices(); + if (verts == null) { + log.debug("No edges in graph for criteria"); + return Either.right(TitanOperationStatus.INVALID_ID); + } + Iterator<Vertex> vIter = verts.iterator(); + if (vIter.hasNext()) { + Vertex vert = vIter.next(); + // vert.getProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String resInstName = vert.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (resInstName.equals(parentId)) + return Either.left(Boolean.TRUE); + } + return Either.left(Boolean.FALSE); + } finally { + if (false == inTransaction) { + titanGraph.tx().commit(); + } + } + } + + public Either<ComponentInstance, TitanOperationStatus> addComponentInstanceToContainerComponent(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLogicaName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted) { + log.debug("Going to create component instance {} in component {}", componentInstance, containerComponentId); + + Either<TitanVertex, TitanOperationStatus> metadataVertex = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), containerComponentId); + if (metadataVertex.isRight()) { + TitanOperationStatus status = metadataVertex.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + Either<TitanVertex, TitanOperationStatus> addComponentInstanceToContainerComponent = addComponentInstanceToContainerComponent(containerComponentId, containerNodeType, instanceNumber, isCreateLogicaName, componentInstance, compInstNodeType, + allowDeleted, metadataVertex.left().value()); + + if (addComponentInstanceToContainerComponent.isRight()) { + TitanOperationStatus status = addComponentInstanceToContainerComponent.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + TitanVertex ciVertex = addComponentInstanceToContainerComponent.left().value(); + Map<String, Object> properties = titanGenericDao.getProperties(ciVertex); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + + ComponentInstance createdResourceInstance = new ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + + return Either.left(createdResourceInstance); + + } + + /** + * + * @param containerComponentId + * @param containerNodeType + * @param instanceNumber + * @param isCreateLogicaName + * @param componentInstance + * @param compInstNodeType + * @param allowDeleted + * @param metadataVertex + * @return + */ + public Either<TitanVertex, TitanOperationStatus> addComponentInstanceToContainerComponent(String containerComponentId, NodeTypeEnum containerNodeType, String instanceNumber, boolean isCreateLogicaName, ComponentInstance componentInstance, + NodeTypeEnum compInstNodeType, boolean allowDeleted, TitanVertex metadataVertex) { + TitanOperationStatus status; + log.debug("Going to create component instance {} in component {}", componentInstance, containerComponentId); + String instOriginComponentId = componentInstance.getComponentUid(); + String logicalName = componentInstance.getName(); + if (isCreateLogicaName) + logicalName = createComponentInstLogicalName(instanceNumber, componentInstance.getName()); + + ComponentInstanceData componentInstanceData = buildComponentInstanceData(componentInstance, containerComponentId, logicalName); + Either<TitanVertex, TitanOperationStatus> originVertexEither = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), instOriginComponentId); + if (originVertexEither.isRight()) { + log.debug("Failed to fetch vertex of origin resource for id {} error {}", instOriginComponentId, originVertexEither.right().value()); + return Either.right(originVertexEither.right().value()); + } + TitanVertex originVertex = originVertexEither.left().value(); + + Boolean isDeleted = (Boolean) titanGenericDao.getProperty(metadataVertex, GraphPropertiesDictionary.IS_DELETED.getProperty()); + + if (!allowDeleted && (isDeleted != null) && (isDeleted == true)) { + log.debug("Component {} is already deleted. Cannot add component instance", instOriginComponentId); + return Either.right(TitanOperationStatus.INVALID_ID); + } + String originType = (String) titanGenericDao.getProperty(originVertex, GraphPropertiesDictionary.LABEL.getProperty()); + String resourceType = (String) titanGenericDao.getProperty(originVertex, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty()); + detectOriginType(originType, componentInstanceData, resourceType); + + log.trace("Before adding component instance to graph. componentInstanceData = {}", componentInstanceData); + + Either<TitanVertex, TitanOperationStatus> createCIResult = titanGenericDao.createNode(componentInstanceData); + + log.debug("After adding component instance to graph. status is = {}", createCIResult); + + if (createCIResult.isRight()) { + status = createCIResult.right().value(); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to create component instance node in graph. status is {}", status); + return Either.right(status); + } + TitanVertex createdComponentInstanceVertex = createCIResult.left().value(); + TitanOperationStatus associateContainerRes = associateContainerCompToComponentInstance(metadataVertex, createdComponentInstanceVertex, logicalName); + + String componentInstanceUniqueId = componentInstanceData.getUniqueId(); + if (!associateContainerRes.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate container component {} to component instance {}. Status is {}", containerComponentId, componentInstanceUniqueId, associateContainerRes); + return Either.right(associateContainerRes); + } + String originId = (String) titanGenericDao.getProperty(createdComponentInstanceVertex, GraphPropertiesDictionary.TYPE.getProperty()); + + TitanOperationStatus associateToInstOriginComponent = associateToInstOriginComponent(createdComponentInstanceVertex, originVertex, originId); + if (!associateToInstOriginComponent.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin component {}. Status is {}", componentInstanceUniqueId, componentInstanceData.getComponentInstDataDefinition().getComponentUid(), associateToInstOriginComponent); + return Either.right(associateToInstOriginComponent); + } + + TitanOperationStatus associateCompInstToRequirements = associateCompInstToRequirements(createdComponentInstanceVertex, containerNodeType, compInstNodeType, originId); + if (!associateCompInstToRequirements.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin requirements. Status is {}", componentInstanceUniqueId, associateCompInstToRequirements); + return Either.right(associateCompInstToRequirements); + } + TitanOperationStatus associateCompInstToCapabilities = associateCompInstToCapabilities(createdComponentInstanceVertex, containerNodeType, compInstNodeType, originId); + if (!associateCompInstToCapabilities.equals(TitanOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeDaoSystemError("Add Component Instance"); + log.debug("Failed to associate component instance {} to its origin capabilities. Status is {}", componentInstanceUniqueId, associateCompInstToCapabilities); + return Either.right(associateCompInstToCapabilities); + } + // Capability instance with property values implementation + Either<List<ImmutablePair<TitanVertex, GraphEdge>>, TitanOperationStatus> cloneCapabilityInstancesRes = null; + Either<List<GraphRelation>, TitanOperationStatus> associateComponentInstanceToCapabilityInstancesRes; + status = null; + if (!isCreateLogicaName) { + // in case of cloning of component instance + log.debug("Before cloning of capability instances of component instance {}.", componentInstance.getUniqueId()); + cloneCapabilityInstancesRes = cloneCapabilityInstancesOfResourceInstance(createdComponentInstanceVertex, componentInstance); + if (cloneCapabilityInstancesRes.isRight() && !cloneCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = cloneCapabilityInstancesRes.right().value(); + log.debug("Failed to clone capability instances of component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After cloning of capability instances of component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } else if (containerNodeType.equals(NodeTypeEnum.Resource) && componentInstance.getCapabilities() != null && !componentInstance.getCapabilities().isEmpty()) { + // in case of creation from scar + TitanOperationStatus addPropertiesRes = createCapabilityInstancesWithPropertyValues(createdComponentInstanceVertex, componentInstanceUniqueId, componentInstance.getCapabilities(), true); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + status = addPropertiesRes; + log.debug("Failed to create capability instances with property values for component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + } + if (status == null && containerNodeType.equals(NodeTypeEnum.Service)) { + Map<String, Object> properties = titanGenericDao.getProperties(createdComponentInstanceVertex); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + if (cloneCapabilityInstancesRes == null || cloneCapabilityInstancesRes.isRight()) { + // in case of creating of service + log.trace("Before associating component instance {} to capability instances .", componentInstance.getUniqueId()); + associateComponentInstanceToCapabilityInstancesRes = associateComponentInstanceToCapabilityInstancesOfResourceInstance(componentInstance); + if (associateComponentInstanceToCapabilityInstancesRes.isRight() && !associateComponentInstanceToCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = associateComponentInstanceToCapabilityInstancesRes.right().value(); + log.debug("Failed to associate capability instances to component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After associating component instance {} to capability instances . Status is {}", componentInstance.getUniqueId(), status); + } else { + // in case of cloning of service + log.trace("Before associating created component instance {} to cloned capability instances.", componentInstanceUniqueId); + TitanOperationStatus associationStatus = associateCreatedComponentInstanceToClonedCapabilityInstances(createdComponentInstanceVertex, componentInstanceUniqueId, cloneCapabilityInstancesRes.left().value()); + if (!associationStatus.equals(TitanOperationStatus.OK) && !associationStatus.equals(TitanOperationStatus.NOT_FOUND)) { + status = associationStatus; + log.debug("Failed to associate capability instances to component instance {}. Status is {}", componentInstance.getUniqueId(), status); + } + log.trace("After associating created component instance {} to cloned capability instances. Status is {}", componentInstanceUniqueId, status); + } + } + if (status == null) { + // ComponentInstance createdResourceInstance = new + // ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + // + // String icon = (String) titanGenericDao.getProperty(originVertex, + // GraphPropertiesDictionary.ICON.getProperty()); + // createdResourceInstance.setIcon(icon); + return Either.left(createdComponentInstanceVertex); + } + return Either.right(status); + } + + private Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> createCapabilityInstancesWithPropertyValues(String resourceInstanceId, Map<String, List<CapabilityDefinition>> capabilities, + boolean isNewlyCreatedResourceInstance) { + TitanOperationStatus error; + Map<CapabilityInstData, List<PropertyValueData>> result = new HashMap<>(); + for (Entry<String, List<CapabilityDefinition>> capailityEntry : capabilities.entrySet()) { + CapabilityDefinition capability = capailityEntry.getValue().get(0); + if (capability.getProperties() != null && !capability.getProperties().isEmpty()) { + Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> addPropertiesRes = addCapabilityPropertyValuesToResourceInstance(resourceInstanceId, capability, isNewlyCreatedResourceInstance); + if (addPropertiesRes.isRight()) { + error = addPropertiesRes.right().value(); + log.debug("Failed to add property values to capabilities of component instance {}. Status is {}", resourceInstanceId, error); + return Either.right(error); + } else { + result.putAll(addPropertiesRes.left().value()); + } + } + } + return Either.left(result); + } + + private TitanOperationStatus createCapabilityInstancesWithPropertyValues(TitanVertex resourceInstanceVertex, String resourceInstanceId, Map<String, List<CapabilityDefinition>> capabilities, boolean isNewlyCreatedResourceInstance) { + TitanOperationStatus result = TitanOperationStatus.OK; + + for (Entry<String, List<CapabilityDefinition>> capailityEntry : capabilities.entrySet()) { + CapabilityDefinition capability = capailityEntry.getValue().get(0); + if (capability.getProperties() != null && !capability.getProperties().isEmpty()) { + TitanOperationStatus addPropertiesRes = addCapabilityPropertyValuesToResourceInstance(resourceInstanceVertex, resourceInstanceId, capability, isNewlyCreatedResourceInstance); + if (!addPropertiesRes.equals(TitanOperationStatus.OK)) { + result = addPropertiesRes; + log.debug("Failed to add property values to capabilities of component instance {}. Status is {}", resourceInstanceId, result); + return result; + } + } + } + return result; + } + + private Either<List<GraphRelation>, TitanOperationStatus> associateCreatedComponentInstanceToClonedCapabilityInstances(String newComponentResourceId, List<ImmutablePair<CapabilityInstData, GraphEdge>> capabilityInstances) { + TitanOperationStatus error = null; + List<GraphRelation> relationsToCapabilityInstances = new ArrayList<>(); + UniqueIdData componentInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, newComponentResourceId); + for (ImmutablePair<CapabilityInstData, GraphEdge> capInstPair : capabilityInstances) { + Either<GraphRelation, TitanOperationStatus> associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createRelation(componentInstanceIdData, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, + capInstPair.getRight().getProperties()); + if (associateComponentInstanceToCapabilityinstanceRes.isRight()) { + error = associateComponentInstanceToCapabilityinstanceRes.right().value(); + log.debug("Failed to associate capability instance {} to resource instance {}. Status is {}.", capInstPair.getLeft().getUniqueId(), newComponentResourceId, error); + break; + } else { + relationsToCapabilityInstances.add(associateComponentInstanceToCapabilityinstanceRes.left().value()); + } + } + if (error == null) { + return Either.left(relationsToCapabilityInstances); + } + return Either.right(error); + } + + private TitanOperationStatus associateCreatedComponentInstanceToClonedCapabilityInstances(TitanVertex riVertex, String newComponentResourceId, List<ImmutablePair<TitanVertex, GraphEdge>> capabilityInstances) { + TitanOperationStatus error = null; + for (ImmutablePair<TitanVertex, GraphEdge> capInstPair : capabilityInstances) { + TitanOperationStatus associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createEdge(riVertex, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, capInstPair.getRight().getProperties()); + if (!associateComponentInstanceToCapabilityinstanceRes.equals(TitanOperationStatus.OK)) { + error = associateComponentInstanceToCapabilityinstanceRes; + log.debug("Failed to associate capability instance {} to resource instance {} status is {} .", capInstPair.getLeft(), newComponentResourceId, error); + break; + } + } + if (error == null) { + return TitanOperationStatus.OK; + } + return error; + } + + private Either<List<GraphRelation>, TitanOperationStatus> associateComponentInstanceToCapabilityInstancesOfResourceInstance(ComponentInstance componentInstance) { + TitanOperationStatus error = null; + String resourceId = componentInstance.getComponentUid(); + String componentResourceId = componentInstance.getUniqueId(); + UniqueIdData componentInstanceIdData = new UniqueIdData(NodeTypeEnum.ResourceInstance, componentResourceId); + List<ImmutablePair<ComponentInstanceData, GraphEdge>> resourceInstancesPair; + List<ImmutablePair<CapabilityInstData, GraphEdge>> allCapabilityInstancesList = new ArrayList<>(); + List<GraphRelation> relationsToCapabilityInstances = new ArrayList<>(); + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> getAllResourceInstanceRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.RESOURCE_INST, NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + if (getAllResourceInstanceRes.isRight() && !getAllResourceInstanceRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllResourceInstanceRes.right().value(); + log.debug("Failed to retrieve resource instances from resource {}. Status is {}.", resourceId, error); + } + if (getAllResourceInstanceRes.isLeft()) { + resourceInstancesPair = getAllResourceInstanceRes.left().value(); + ComponentInstanceData ri; + for (ImmutablePair<ComponentInstanceData, GraphEdge> riPair : resourceInstancesPair) { + ri = riPair.getLeft(); + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), ri.getUniqueId(), + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability instances of resource instance {}. Status is {}", ri.getUniqueId(), error); + break; + } + if (getCapabilityInstancesRes.isLeft()) { + allCapabilityInstancesList.addAll(getCapabilityInstancesRes.left().value()); + } + } + } + if (error == null && !allCapabilityInstancesList.isEmpty()) { + for (ImmutablePair<CapabilityInstData, GraphEdge> capInstPair : allCapabilityInstancesList) { + Either<GraphRelation, TitanOperationStatus> associateComponentInstanceToCapabilityinstanceRes = titanGenericDao.createRelation(componentInstanceIdData, capInstPair.getLeft(), GraphEdgeLabels.CAPABILITY_INST, + capInstPair.getRight().getProperties()); + if (associateComponentInstanceToCapabilityinstanceRes.isRight()) { + error = associateComponentInstanceToCapabilityinstanceRes.right().value(); + log.debug("Failed to associate capability instance {} to resource instance {}. Status is {}", capInstPair.getLeft().getUniqueId(), componentResourceId, error); + break; + } else { + relationsToCapabilityInstances.add(associateComponentInstanceToCapabilityinstanceRes.left().value()); + } + } + } + if (error == null) { + return Either.left(relationsToCapabilityInstances); + } + return Either.right(error); + } + + private void detectOriginType(String label, ComponentInstanceData componentInstanceData, String resourceTypeStr) { + switch (NodeTypeEnum.getByName(label)) { + case Service: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.SERVICE); + break; + case Product: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.PRODUCT); + break; + case Resource: + ResourceTypeEnum resourceType = ResourceTypeEnum.valueOf(resourceTypeStr); + switch (resourceType) { + case VF: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VF); + break; + case VFC: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VFC); + break; + case CP: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.CP); + break; + case VL: + componentInstanceData.getComponentInstDataDefinition().setOriginType(OriginTypeEnum.VL); + break; + } + break; + default: + break; + } + } + + private Either<GraphRelation, TitanOperationStatus> associateToInstOriginComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum compInstNodeType) { + + UniqueIdData resourceIdData = new UniqueIdData(compInstNodeType, componentInstanceData.getComponentInstDataDefinition().getComponentUid()); + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(componentInstanceData, resourceIdData, GraphEdgeLabels.INSTANCE_OF, null); + + log.debug("After associating resource instance {} to resource {}. Status is {}", + componentInstanceData.getUniqueId(), + componentInstanceData.getComponentInstDataDefinition().getUniqueId(), + createRelation); + + return createRelation; + } + + private TitanOperationStatus associateToInstOriginComponent(TitanVertex componentInstanceVertex, TitanVertex originVertex, String originId) { + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, originVertex, GraphEdgeLabels.INSTANCE_OF, null); + + log.debug("After associating resource instance {} to resource {}. status is {}", componentInstanceVertex, originId, createRelation); + + return createRelation; + } + + private Either<List<GraphRelation>, TitanOperationStatus> associateCompInstToRequirements(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + log.trace("Starting to copy origin component requirements to its component instance"); + String compInstOriginId = componentInstanceData.getComponentInstDataDefinition().getComponentUid(); + List<GraphRelation> graphRelations = new ArrayList<>(); + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + createRequirementRelationsFromAtomicResource(componentInstanceData, compInstOriginId, graphRelations); + + } + // case of VF / Service / Product + createCalculatedRequirementRelationsFromComponent(componentInstanceData, containerNodeType, compInstNodeType, graphRelations, compInstOriginId); + + log.trace("Finished to copy origin component requirements to its component instance, created {} new calculated requirement relations", graphRelations.size()); + return Either.left(graphRelations); + } + + private TitanOperationStatus associateCompInstToRequirements(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String originId) { + log.trace("Starting to copy origin component requirements to its component instance"); + TitanOperationStatus status = TitanOperationStatus.OK; + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + status = createRequirementRelationsFromAtomicResource(componentInstanceVertex, originId); + if (!status.equals(TitanOperationStatus.OK)) { + log.debug("Failed create relation to requirement of origin {} error {}", originId, status); + return status; + } + } + // case of VF / Service / Product + status = createCalculatedRequirementRelationsFromComponent(componentInstanceVertex, containerNodeType, compInstNodeType, originId); + + log.trace("Finished to copy origin component requirements to its component instance with status {}", status); + return status; + } + + private void createRequirementRelationsFromAtomicResource(ComponentInstanceData componentInstanceData, String compInstOriginId, List<GraphRelation> graphRelations) { + Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>(); + Set<String> caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = requirementOperation.findAllRequirementsRecursively(compInstOriginId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK) { + log.debug("Couldn't fetch requirements of component {}, error: {}", compInstOriginId, status); + } + + log.trace("Found {} requirements for component {}, ", requirements.size(), compInstOriginId); + for (Entry<String, RequirementDefinition> reqPair : requirements.entrySet()) { + RequirementDefinition requirementDef = reqPair.getValue(); + RequirementData requirementData = new RequirementData(); + requirementData.setUniqueId(requirementDef.getUniqueId()); + + log.trace("Creating calculated requirement relation from component instance {} to requirement {}", componentInstanceData.getUniqueId(), requirementDef.getUniqueId()); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), reqPair.getKey()); + + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstanceData.getUniqueId()); + if (requirementDef.getMinOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), RequirementData.MIN_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requirementDef.getMinOccurrences()); + } + if (requirementDef.getMaxOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), RequirementData.MAX_DEFAULT_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), requirementDef.getMaxOccurrences()); + } + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(componentInstanceData, requirementData, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", componentInstanceData.getUniqueId(), requirementDef.getUniqueId(), titanOperationStatus); + } + graphRelations.add(createRelation.left().value()); + } + } + + private TitanOperationStatus createRequirementRelationsFromAtomicResource(TitanVertex componentInstanceVertex, String compInstOriginId) { + Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>(); + Set<String> caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = requirementOperation.findAllRequirementsRecursively(compInstOriginId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch requirements of component {}, error: {}", compInstOriginId, status); + return status; + } + + String compoInstId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + log.trace("Found {} requirements for component {}, ", requirements.size(), compInstOriginId); + for (Entry<String, RequirementDefinition> reqPair : requirements.entrySet()) { + RequirementDefinition requirementDef = reqPair.getValue(); + RequirementData requirementData = new RequirementData(); + requirementData.setUniqueId(requirementDef.getUniqueId()); + + log.trace("Creating calculated requirement relation from component instance {} to requirement {}", compoInstId, requirementDef.getUniqueId()); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), reqPair.getKey()); + + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), compoInstId); + if (requirementDef.getMinOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), RequirementData.MIN_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requirementDef.getMinOccurrences()); + } + if (requirementDef.getMaxOccurrences() == null) { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), RequirementData.MAX_DEFAULT_OCCURRENCES); + } else { + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), requirementDef.getMaxOccurrences()); + } + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, requirementData, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", compoInstId, requirementDef.getUniqueId(), createRelation); + return createRelation; + } + } + return TitanOperationStatus.OK; + } + + private Either<List<GraphRelation>, TitanOperationStatus> associateCompInstToCapabilities(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + log.trace("Starting to copy origin component capabilities to its component instance"); + List<GraphRelation> graphRelations = new ArrayList<>(); + + String compInstOriginId = componentInstanceData.getComponentInstDataDefinition().getComponentUid(); + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + createCaculatedRelationsFromAtomicResource(componentInstanceData, graphRelations, compInstOriginId); + } + + // case of VF / Service / Product + createCalculatedCapabilityRelationsFromComponent(componentInstanceData, containerNodeType, compInstNodeType, graphRelations, compInstOriginId); + + log.trace("Finished to copy origin component capabilities to its component instance, created {} new calculated capability relations", graphRelations.size()); + return Either.left(graphRelations); + } + + private TitanOperationStatus associateCompInstToCapabilities(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String originId) { + + log.trace("Starting to copy origin component capabilities to its component instance"); + TitanOperationStatus status = TitanOperationStatus.OK; + + // case of VFC / CP / VL + if (compInstNodeType.equals(NodeTypeEnum.Resource)) { + status = createCaculatedRelationsFromAtomicResource(componentInstanceVertex, originId); + if (!status.equals(TitanOperationStatus.OK)) { + return status; + } + } + + // case of VF / Service / Product + status = createCalculatedCapabilityRelationsFromComponent(componentInstanceVertex, containerNodeType, compInstNodeType, originId); + + return status; + } + + private void createCalculatedRequirementRelationsFromComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, List<GraphRelation> graphRelations, String compInstOriginId) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List<ComponentInstance> componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_REQUIREMENT, NodeTypeEnum.Requirement, RequirementData.class); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List<ImmutablePair<RequirementData, GraphEdge>> list = childrenNodes.left().value(); + for (ImmutablePair<RequirementData, GraphEdge> calculatedReq : list) { + + GraphEdge edge = calculatedReq.right; + Map<String, Object> properties = edge.getProperties(); + String source = null; + String occurrences = RequirementData.MAX_DEFAULT_OCCURRENCES; + String minOccurrences = RequirementData.MIN_OCCURRENCES; + + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + Either<GraphRelation, TitanOperationStatus> createRelation = createCalculatedRequirementEdge(componentInstanceData, source, capabilityName, calculatedReq.left, componentInstance, occurrences, minOccurrences); + if (createRelation.isLeft()) { + graphRelations.add(createRelation.left().value()); + } + } + } + } + } + } + + private TitanOperationStatus createCalculatedRequirementRelationsFromComponent(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String compInstOriginId) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List<ComponentInstance> componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + + Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_REQUIREMENT); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List<ImmutablePair<TitanVertex, Edge>> list = childrenNodes.left().value(); + for (ImmutablePair<TitanVertex, Edge> calculatedReq : list) { + + Edge edge = calculatedReq.right; + Map<String, Object> properties = titanGenericDao.getProperties(edge); + String source = null; + String occurrences = RequirementData.MAX_DEFAULT_OCCURRENCES; + String minOccurrences = RequirementData.MIN_OCCURRENCES; + + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + TitanOperationStatus createRelation = createCalculatedRequirementEdge(componentInstanceVertex, source, capabilityName, calculatedReq.left, componentInstance, occurrences, minOccurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement edge, status ", createRelation); + return createRelation; + } + } + } + } + } + return TitanOperationStatus.OK; + } + + private void createCalculatedCapabilityRelationsFromComponent(ComponentInstanceData componentInstanceData, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, List<GraphRelation> graphRelations, String compInstOriginId) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List<ComponentInstance> componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(compInstNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, CapabilityData.class); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List<ImmutablePair<CapabilityData, GraphEdge>> list = childrenNodes.left().value(); + for (ImmutablePair<CapabilityData, GraphEdge> calculatedCap : list) { + + GraphEdge edge = calculatedCap.right; + Map<String, Object> properties = edge.getProperties(); + String source = null; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + Either<GraphRelation, TitanOperationStatus> createRelation = createCalculatedCapabilityEdge(componentInstanceData, source, capabilityName, calculatedCap.left, componentInstance.getUniqueId(), minOccurrences, occurrences); + if (createRelation.isLeft()) { + graphRelations.add(createRelation.left().value()); + } + } + } + } + } + } + + private TitanOperationStatus createCalculatedCapabilityRelationsFromComponent(TitanVertex componentInstanceVertex, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, String compInstOriginId) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> componentInstancesOfComponent = getComponentInstancesOfComponent(compInstOriginId, containerNodeType, compInstNodeType); + if (componentInstancesOfComponent.isLeft() && !componentInstancesOfComponent.left().value().left.isEmpty()) { + List<ComponentInstance> componentInstances = componentInstancesOfComponent.left().value().left; + for (ComponentInstance componentInstance : componentInstances) { + Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(compInstNodeType), componentInstance.getUniqueId(), + GraphEdgeLabels.CALCULATED_CAPABILITY); + + if (childrenNodes.isLeft() && !childrenNodes.left().value().isEmpty()) { + List<ImmutablePair<TitanVertex, Edge>> list = childrenNodes.left().value(); + for (ImmutablePair<TitanVertex, Edge> calculatedCap : list) { + + Edge edge = calculatedCap.right; + Map<String, Object> properties = titanGenericDao.getProperties(edge); + String source = null; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.SOURCE.getProperty())) { + source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + } + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty())) { + minOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + } + if (properties != null && properties.containsKey(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty())) { + occurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + } + + String capabilityName = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + TitanOperationStatus createRelation = createCalculatedCapabilityEdge(componentInstanceVertex, source, capabilityName, calculatedCap.left, componentInstance.getUniqueId(), minOccurrences, occurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return createRelation; + } + } + } + } + } + return TitanOperationStatus.OK; + } + + private void createCaculatedRelationsFromAtomicResource(ComponentInstanceData componentInstanceData, List<GraphRelation> graphRelations, String compInstOriginId) { + + Map<String, CapabilityDefinition> capabilities = new HashMap<String, CapabilityDefinition>(); + Set<String> caseInsensitiveCapNames = new HashSet<>(); + TitanOperationStatus getAllCapabilities = capabilityOperation.getAllCapabilitiesRecusive(NodeTypeEnum.Resource, compInstOriginId, true, capabilities, caseInsensitiveCapNames, true); + + if (!getAllCapabilities.equals(TitanOperationStatus.OK)) { + if (getAllCapabilities != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch capabilities of component {}, error: {}", compInstOriginId, getAllCapabilities); + return; + } + } + log.trace("Found {} capabilities for component {}, ", capabilities.size(), compInstOriginId); + for (Entry<String, CapabilityDefinition> capPair : capabilities.entrySet()) { + CapabilityDefinition capabilityData = capPair.getValue(); + log.trace("Creating calculated capability relation from component instance {} to capability {}", componentInstanceData.getUniqueId(), capabilityData.getUniqueId()); + CapabilityData capabilityDataNode = new CapabilityData(); + capabilityDataNode.setUniqueId(capabilityData.getUniqueId()); + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (capabilityData.getMinOccurrences() != null) { + minOccurrences = capabilityData.getMinOccurrences(); + } + if (capabilityData.getMinOccurrences() != null) { + occurrences = capabilityData.getMaxOccurrences(); + } + + Either<GraphRelation, TitanOperationStatus> createRelation = createCalculatedCapabilityEdge(componentInstanceData, compInstOriginId, capPair.getKey(), capabilityDataNode, componentInstanceData.getUniqueId(), minOccurrences, occurrences); + graphRelations.add(createRelation.left().value()); + } + } + + private TitanOperationStatus createCaculatedRelationsFromAtomicResource(TitanVertex componentInstanceVertex, String compInstOriginId) { + + Map<String, CapabilityDefinition> capabilities = new HashMap<String, CapabilityDefinition>(); + Set<String> caseInsensitiveCapNames = new HashSet<>(); + TitanOperationStatus getAllCapabilities = capabilityOperation.getAllCapabilitiesRecusive(NodeTypeEnum.Resource, compInstOriginId, true, capabilities, caseInsensitiveCapNames, true); + + if (!getAllCapabilities.equals(TitanOperationStatus.OK)) { + if (getAllCapabilities != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch capabilities of component {}, error: {}", compInstOriginId, getAllCapabilities); + } + } + log.trace("Found {} capabilities for component {}, ", capabilities.size(), compInstOriginId); + String compoInstId = (String) titanGenericDao.getProperty(componentInstanceVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + for (Entry<String, CapabilityDefinition> capPair : capabilities.entrySet()) { + CapabilityDefinition capabilityData = capPair.getValue(); + log.trace("Creating calculated capability relation from component instance {} to capability {}", compoInstId, capabilityData.getUniqueId()); + CapabilityData capabilityDataNode = new CapabilityData(); + capabilityDataNode.setUniqueId(capabilityData.getUniqueId()); + String minOccurrences = CapabilityData.MIN_OCCURRENCES; + String occurrences = CapabilityData.MAX_OCCURRENCES; + if (capabilityData.getMinOccurrences() != null) { + minOccurrences = capabilityData.getMinOccurrences(); + } + if (capabilityData.getMinOccurrences() != null) { + occurrences = capabilityData.getMaxOccurrences(); + } + + TitanOperationStatus createRelation = createCalculatedCapabilityEdge(componentInstanceVertex, compInstOriginId, capPair.getKey(), capabilityDataNode, compoInstId, minOccurrences, occurrences); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return createRelation; + } + } + return TitanOperationStatus.OK; + } + + private Either<GraphRelation, TitanOperationStatus> createCalculatedCapabilityEdge(ComponentInstanceData componentInstanceData, String compInstOriginId, String capabilityName, CapabilityData capabilityDataNode, String componentInstanceId, + String minOccurrences, String occurrences) { + Map<String, Object> props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(componentInstanceData, capabilityDataNode, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceData.getUniqueId(), capabilityDataNode.getUniqueId(), titanOperationStatus); + return Either.right(titanOperationStatus); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedCapabilityEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, CapabilityData capabilityDataNode, String componentInstanceId, String minOccurrences, + String occurrences) { + Map<String, Object> props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, capabilityDataNode, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceId, capabilityDataNode.getUniqueId(), createRelation); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedCapabilityEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, TitanVertex capabilityDataVertex, String componentInstanceId, String minOccurrences, + String occurrences) { + Map<String, Object> props = prepareEdgeCapabiltyProperites(compInstOriginId, capabilityName, componentInstanceId, minOccurrences, occurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, capabilityDataVertex, GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated capability from component instance {} to capability {}, error: {}", componentInstanceId, capabilityName, createRelation); + } + return createRelation; + } + + private Map<String, Object> prepareEdgeCapabiltyProperites(String compInstOriginId, String capabilityName, String componentInstanceId, String minOccurrences, String occurrences) { + Map<String, Object> props = new HashMap<String, Object>(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstanceId != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstanceId); + } + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + return props; + } + + private Either<GraphRelation, TitanOperationStatus> createCalculatedRequirementEdge(ComponentInstanceData componentInstanceData, String compInstOriginId, String capabilityName, RequirementData requirementData, ComponentInstance componentInstance, + String occurrences, String minOccurrences) { + Map<String, Object> props = new HashMap<String, Object>(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstance != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstance.getUniqueId()); + } + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(componentInstanceData, requirementData, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", componentInstanceData.getUniqueId(), requirementData.getUniqueId(), titanOperationStatus); + return Either.right(titanOperationStatus); + } + return createRelation; + } + + private TitanOperationStatus createCalculatedRequirementEdge(TitanVertex componentInstanceVertex, String compInstOriginId, String capabilityName, TitanVertex requirementVertex, ComponentInstance componentInstance, String occurrences, + String minOccurrences) { + Map<String, Object> props = new HashMap<String, Object>(); + if (capabilityName != null) + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capabilityName); + if (compInstOriginId != null) + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), compInstOriginId); + if (componentInstance != null) { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), componentInstance.getUniqueId()); + } + props.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), occurrences); + props.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), minOccurrences); + + TitanOperationStatus createRelation = titanGenericDao.createEdge(componentInstanceVertex, requirementVertex, GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (!createRelation.equals(TitanOperationStatus.OK)) { + log.debug("Failed to create calculated requirement from component instance {} to requirement {}, error: {}", componentInstance.getUniqueId(), capabilityName, createRelation); + return createRelation; + } + return createRelation; + } + + /** + * Make a relation between service to resource instance. + * + * @param containerCompIdData + * @param componentInstanceData + * @param logicalName + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateContainerCompToComponentInstance(UniqueIdData containerCompIdData, ComponentInstanceData componentInstanceData, String logicalName) { + Map<String, Object> properties = new HashMap<String, Object>(); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), logicalName); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(containerCompIdData, componentInstanceData, GraphEdgeLabels.RESOURCE_INST, properties); + + log.debug("After associating container component {} to resource instance {} with logical name {}. Status is {}", containerCompIdData.getUniqueId(), componentInstanceData.getUniqueId(), logicalName, createRelation); + + return createRelation; + } + + private TitanOperationStatus associateContainerCompToComponentInstance(TitanVertex containerCompVertex, TitanVertex componentInstanceVertex, String logicalName) { + Map<String, Object> properties = new HashMap<String, Object>(); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), logicalName); + TitanOperationStatus createRelation = titanGenericDao.createEdge(containerCompVertex, componentInstanceVertex, GraphEdgeLabels.RESOURCE_INST, properties); + + return createRelation; + } + + @Override + public String createComponentInstLogicalName(String instanceNumber, String componentInstanceName) { + + String logicalName = buildComponentInstanceLogicalName(instanceNumber, componentInstanceName); + + return logicalName; + } + + private String buildComponentInstanceLogicalName(String instanceNumber, String lastToken) { + return lastToken + " " + (instanceNumber == null ? 0 : instanceNumber); + } + + private ComponentInstanceData buildComponentInstanceData(ComponentInstance resourceInstance, String componentId, String logicalName) { + + String ciOriginComponentUid = resourceInstance.getComponentUid(); + + ComponentInstanceDataDefinition dataDefinition = new ComponentInstanceDataDefinition(resourceInstance); + + Long creationDate = resourceInstance.getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + dataDefinition.setCreationTime(creationDate); + dataDefinition.setModificationTime(creationDate); + // dataDefinition.setResourceUid(resourceUid); + // String replacmentlogicalName = logicalName.replaceAll(" ", + // "_").toLowerCase(); + dataDefinition.setName(logicalName); + if (dataDefinition.getNormalizedName() == null) + dataDefinition.setNormalizedName(ValidationUtils.normaliseComponentInstanceName(logicalName)); + dataDefinition.setUniqueId(UniqueIdBuilder.buildResourceInstanceUniuqeId(componentId, ciOriginComponentUid, dataDefinition.getNormalizedName())); + + ComponentInstanceData resourceInstanceData = new ComponentInstanceData(dataDefinition); + + return resourceInstanceData; + } + + public Either<ComponentInstance, TitanOperationStatus> removeComponentInstanceFromComponent(NodeTypeEnum containerNodeType, String containerComponentId, String componentInstanceUid) { + + log.debug("Going to delete component instance {} under component {}", componentInstanceUid, containerComponentId); + + Either<ComponentInstanceData, TitanOperationStatus> node = findResourceInstance(componentInstanceUid); + + if (node.isRight()) { + TitanOperationStatus status = node.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Remove Component Instance"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Remove Component Instance"); + log.debug("Failed to delete component instance {}. Status is {}", componentInstanceUid, status); + return Either.right(status); + } + + TitanOperationStatus isComponentInstOfComponent = verifyResourceInstanceUnderComponent(containerNodeType, containerComponentId, componentInstanceUid); + if (isComponentInstOfComponent != TitanOperationStatus.OK) { + return Either.right(isComponentInstOfComponent); + } + + TitanOperationStatus status = deleteOutgoingRelationships(containerNodeType, containerComponentId, componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + status = deleteIncomingRelationships(containerNodeType, containerComponentId, componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated properties + status = deleteAssociatedProperties(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + // delete associated properties + status = deleteAssociatedAttributes(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated artifacts + status = deleteAssociatedArtifacts(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + // delete associated capability instances + if (containerNodeType.equals(NodeTypeEnum.Resource)) { + status = deleteAssociatedCapabilityInstances(componentInstanceUid); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + Either<ComponentInstanceData, TitanOperationStatus> deleteRI = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), componentInstanceUid, ComponentInstanceData.class); + + if (deleteRI.isRight()) { + TitanOperationStatus deleteRiStatus = deleteRI.right().value(); + log.error("Failed to delete resource instance {}. Status is {}", componentInstanceUid, deleteRiStatus); + return Either.right(deleteRiStatus); + } + + ComponentInstanceData deletedResourceInst = deleteRI.left().value(); + + ComponentInstance resourceInstance = new ComponentInstance(deletedResourceInst.getComponentInstDataDefinition()); + + return Either.left(resourceInstance); + } + + private TitanOperationStatus deleteAssociatedCapabilityInstances(String resourceInstanceId) { + TitanOperationStatus status = TitanOperationStatus.OK; + + log.debug("Before deleting all capability instances of component istance {}.", resourceInstanceId); + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, + GraphEdgeLabels.CAPABILITY_INST, NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + status = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {}. Status is {}", resourceInstanceId, status); + } + if (getCapabilityInstancesRes.isLeft()) { + for (ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstancePair : getCapabilityInstancesRes.left().value()) { + Either<CapabilityInstData, TitanOperationStatus> deleteCababilityInstanceRes = capabilityInstanceOperation.deleteCapabilityInstanceFromResourceInstance(resourceInstanceId, capabilityInstancePair.getLeft().getUniqueId()); + if (deleteCababilityInstanceRes.isRight()) { + status = deleteCababilityInstanceRes.right().value(); + } + } + } + log.debug("After deleting all capability instances of component istance {}. Status is {}", resourceInstanceId, status); + return status; + } + + private TitanOperationStatus deleteAssociatedArtifacts(String resourceInstanceUid) { + + Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> artifactRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, GraphEdgeLabels.ARTIFACT_REF, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + + if (artifactRes.isRight()) { + TitanOperationStatus status = artifactRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find artifacts of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + } else { + + List<ImmutablePair<ArtifactData, GraphEdge>> artifactPairs = artifactRes.left().value(); + for (ImmutablePair<ArtifactData, GraphEdge> pair : artifactPairs) { + String uniqueId = (String) pair.left.getUniqueId(); + Either<ArtifactData, TitanOperationStatus> removeArifactFromGraph = artifactOperation.removeArtifactOnGraph(resourceInstanceUid, uniqueId, NodeTypeEnum.ResourceInstance, resourceInstanceUid, true); + if (removeArifactFromGraph.isRight()) { + TitanOperationStatus status = removeArifactFromGraph.right().value(); + log.error("Failed to delete artifact of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + + } + } + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus deleteAssociatedProperties(String resourceInstanceUid) { + final GraphEdgeLabels edgeConectingToRI = GraphEdgeLabels.PROPERTY_VALUE; + final NodeTypeEnum elementTypeToDelete = NodeTypeEnum.PropertyValue; + return deleteAssociatedRIElements(elementTypeToDelete, edgeConectingToRI, resourceInstanceUid, () -> PropertyValueData.class); + + } + + private TitanOperationStatus deleteAssociatedAttributes(String resourceInstanceUid) { + final GraphEdgeLabels edgeConectingToRI = GraphEdgeLabels.ATTRIBUTE_VALUE; + final NodeTypeEnum elementTypeToDelete = NodeTypeEnum.AttributeValue; + return deleteAssociatedRIElements(elementTypeToDelete, edgeConectingToRI, resourceInstanceUid, () -> AttributeValueData.class); + } + + private <T extends GraphNode> TitanOperationStatus deleteAssociatedRIElements(NodeTypeEnum elementTypeToDelete, GraphEdgeLabels edgeConectingToRI, String resourceInstanceUid, Supplier<Class<T>> classGen) { + + Either<List<ImmutablePair<T, GraphEdge>>, TitanOperationStatus> elementsNodesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, edgeConectingToRI, elementTypeToDelete, + classGen.get()); + + if (elementsNodesRes.isRight()) { + TitanOperationStatus status = elementsNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("deleteAssociatedRIElements", "Failed to find the elements of resource instance " + resourceInstanceUid + ". status is " + status, ErrorSeverity.ERROR); + return status; + } + } else { + + List<ImmutablePair<T, GraphEdge>> relationshipNodes = elementsNodesRes.left().value(); + if (relationshipNodes != null) { + for (ImmutablePair<T, GraphEdge> immutablePair : relationshipNodes) { + T elementValueDataData = immutablePair.getKey(); + Either<T, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(elementValueDataData, classGen.get()); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("deleteAssociatedRIElements", "Failed to delete element value node " + elementValueDataData + ". status is " + status, ErrorSeverity.ERROR); + return status; + } + } + } + + } + + return TitanOperationStatus.OK; + } + + /** + * delete all relationship instance nodes which has an outgoing edge to a given resource instance + * + * @param resourceInstanceUid + * @return + */ + private TitanOperationStatus deleteIncomingRelationships(NodeTypeEnum componentType, String componentId, String resourceInstanceUid) { + + Either<List<RequirementCapabilityRelDef>, TitanOperationStatus> relationsForTarget = getRelationsForTarget(resourceInstanceUid); + if (relationsForTarget.isRight()) { + TitanOperationStatus status = relationsForTarget.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the relationships of resource instance {}. Status is {}", resourceInstanceUid, status); + return status; + } + } else { + List<RequirementCapabilityRelDef> relList = relationsForTarget.left().value(); + for (RequirementCapabilityRelDef relation : relList) { + Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances = dissociateResourceInstances(componentId, componentType, relation, true); + if (dissociateResourceInstances.isRight()) { + log.error("failed to diassociate component instance {} and component instance {} under component {}. error is {}", relation.getFromNode(), relation.getToNode(), componentId); + return TitanOperationStatus.GENERAL_ERROR; + } + } + } + return TitanOperationStatus.OK; + } + + /** + * delete all relationship instance nodes which has an incoming edge from a given resource instance + * + * @param resourceInstanceUid + * @return + */ + private TitanOperationStatus deleteOutgoingRelationships(NodeTypeEnum componentType, String componentId, String resourceInstanceUid) { + + Either<List<RequirementCapabilityRelDef>, TitanOperationStatus> relationsForSource = getRelationsForSource(resourceInstanceUid); + if (relationsForSource.isRight()) { + TitanOperationStatus status = relationsForSource.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the relationships of resource instance " + resourceInstanceUid + ". status is " + status); + return status; + } + } else { + List<RequirementCapabilityRelDef> relList = relationsForSource.left().value(); + for (RequirementCapabilityRelDef relation : relList) { + Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances = dissociateResourceInstances(componentId, componentType, relation, true); + if (dissociateResourceInstances.isRight()) { + log.error("failed to diassociate component instance {} and component instance {} under component {}. error is {}", relation.getFromNode(), relation.getToNode(), componentId); + return TitanOperationStatus.GENERAL_ERROR; + } + } + } + return TitanOperationStatus.OK; + } + + /** + * delete relationship instance nodes + * + * @param relationshipNodes + * @return + */ + private TitanOperationStatus deleteRelationshipNodes(List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipNodes) { + + if (relationshipNodes != null) { + for (ImmutablePair<RelationshipInstData, GraphEdge> immutablePair : relationshipNodes) { + RelationshipInstData relationshipTypeImplData = immutablePair.getKey(); + Either<RelationshipInstData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(relationshipTypeImplData, RelationshipInstData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + log.error("Failed to delete relationship node {}. Status is {}", relationshipTypeImplData, status); + return status; + } + } + } + + return TitanOperationStatus.OK; + } + + public Either<List<RelationshipInstData>, TitanOperationStatus> disconnectResourcesInService(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef) { + + if (requirementDef.getRelationships() == null) { + log.debug("No relation pair in request [ {} ]", requirementDef); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + String fromResInstanceUid = requirementDef.getFromNode(); + String toResInstanceUid = requirementDef.getToNode(); + + // DE191707 + TitanOperationStatus isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, fromResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, toResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + + List<RequirementAndRelationshipPair> relationPairList = requirementDef.getRelationships(); + + Either<TitanVertex, TitanOperationStatus> riFrom = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstanceUid); + if (riFrom.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", fromResInstanceUid, riFrom.right().value()); + return Either.right(riFrom.right().value()); + } + Iterator<Edge> edgeIter = riFrom.left().value().edges(Direction.OUT, GraphEdgeLabels.RELATIONSHIP_INST.getProperty()); + if (edgeIter == null) { + log.debug("No edges with label {} for owner RI {}", GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED.getProperty(), fromResInstanceUid); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + List<RelationshipInstData> deletedRelations = new ArrayList<>(); + List<String> vertexToDelete = new ArrayList<>(); + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + String name = (String) edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + for (RequirementAndRelationshipPair relationPair : relationPairList) { + if (relationPair.getRequirement().equals(name)) { + TitanVertex inVertex = edge.inVertex(); + String requirementId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.REQUIREMENT_ID.getProperty()); + String capabiltyId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.CAPABILITY_ID.getProperty()); + String requirementOwnerId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.REQUIREMENT_OWNER_ID.getProperty()); + String capabiltyOwnerId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.CAPABILITY_OWNER_ID.getProperty()); + String relationVertexId = (String) titanGenericDao.getProperty(inVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + // verify vs requirement id and owner ids. ( for + // requirements with same name) + if (requirementId.equals(relationPair.getRequirementUid()) && capabiltyId.equals(relationPair.getCapabilityUid()) && requirementOwnerId.equals(relationPair.getRequirementOwnerId()) + && capabiltyOwnerId.equals(relationPair.getCapabilityOwnerId())) { + vertexToDelete.add(relationVertexId); + } + } + } + } + log.debug("relation node with ids: {} are going to be deleted", vertexToDelete); + for (String relationVertexId : vertexToDelete) { + // remove relation vertex + Either<RelationshipInstData, TitanOperationStatus> relationNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipInst), relationVertexId, RelationshipInstData.class); + if (relationNode.isRight()) { + log.debug("Failed to delete relation node with id {}. Error: {}", relationVertexId, relationNode.right().value()); + return Either.right(relationNode.right().value()); + } + RelationshipInstData deletedRelation = relationNode.left().value(); + deletedRelations.add(deletedRelation); + } + if (deletedRelations.size() > 0) { + return Either.left(deletedRelations); + } + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + @Override + public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef, boolean inTransaction) { + + String fromResInstanceUid = requirementDef.getFromNode(); + String toResInstanceUid = requirementDef.getToNode(); + String requirement = requirementDef.getRelationships().get(0).getRequirement(); + Either<RequirementCapabilityRelDef, StorageOperationStatus> result = null; + try { + + Either<List<RelationshipInstData>, TitanOperationStatus> dissociateRes = disconnectResourcesInService(componentId, nodeType, requirementDef); + if (dissociateRes.isRight()) { + TitanOperationStatus status = dissociateRes.right().value(); + log.error("Failed to dissociate resource instance " + fromResInstanceUid + " from resource instance " + toResInstanceUid + " in service " + componentId + ". status is " + status); + BeEcompErrorManager.getInstance().logBeDaoSystemError("dissociateComponentInstances"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + StorageOperationStatus updateCalculatedCapReqResult = updateCalculatedCapReq(requirementDef, false); + if (!updateCalculatedCapReqResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "dissociateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("dissociateComponentInstances"); + log.debug("Failed to dissociate component instances {}. Status is {}", requirementDef, updateCalculatedCapReqResult); + result = Either.right(updateCalculatedCapReqResult); + return result; + } + + // RelationshipInstData relationshipInstData = + // dissociateRes.left().value(); + List<RelationshipInstData> relationshipInstData = dissociateRes.left().value(); + RequirementCapabilityRelDef capabilityRelDef = buildCapabilityResult(fromResInstanceUid, toResInstanceUid, requirement, relationshipInstData); + + result = Either.left(capabilityRelDef); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + private StorageOperationStatus updateCalculatedCapReq(RequirementCapabilityRelDef capabilityRelDef, boolean associate) { + GraphEdgeLabels requirmentNewLabel = associate ? GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED : GraphEdgeLabels.CALCULATED_REQUIREMENT; + + GraphEdgeLabels requirmentCurrentLabel = associate ? GraphEdgeLabels.CALCULATED_REQUIREMENT : GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED; + + GraphEdgeLabels capabilityNewLabel = associate ? GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED : GraphEdgeLabels.CALCULATED_CAPABILITY; + + GraphEdgeLabels capabilityCurrentLabel = associate ? GraphEdgeLabels.CALCULATED_CAPABILITY : GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED; + + List<RequirementAndRelationshipPair> relationships = capabilityRelDef.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + StorageOperationStatus status = updateRequirementEdges(requirmentNewLabel, requirmentCurrentLabel, pair, capabilityRelDef.getFromNode()); + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + status = updateCapabiltyEdges(capabilityNewLabel, capabilityCurrentLabel, pair, capabilityRelDef.getToNode()); + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus updateRequirementEdges(GraphEdgeLabels requirmentNewLabel, GraphEdgeLabels requirmentCurrentLabel, RequirementAndRelationshipPair pair, String requirementOwnerId) { + Either<TitanVertex, TitanOperationStatus> reqOwnerRI = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), requirementOwnerId); + if (reqOwnerRI.isRight()) { + log.debug("Failed to fetch requirment Owner by Id {}. Error: {}", requirementOwnerId, reqOwnerRI.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(reqOwnerRI.right().value()); + } + Iterator<Edge> edgeIter = reqOwnerRI.left().value().edges(Direction.OUT, requirmentCurrentLabel.name(), requirmentNewLabel.name()); + if (edgeIter == null) { + log.debug("No edges with label {} for woner RI {}", requirmentCurrentLabel, requirementOwnerId); + return StorageOperationStatus.GENERAL_ERROR; + } + boolean associate = requirmentNewLabel.equals(GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED) ? true : false; + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + String name = (String) edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + if (pair.getRequirement().equals(name)) { + TitanVertex reqVertex = edge.inVertex(); + String requirementId = (String) titanGenericDao.getProperty(reqVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + // verify vs requirement id . ( for requirements with same name) + if (requirementId.equals(pair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(pair.getRequirementOwnerId())) { + String requiredOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + + String requiredOccurrencesNew = "0"; + String leftOccurrencesNew = RequirementData.MAX_DEFAULT_OCCURRENCES; + if (requiredOccurrences != null) { + Integer iOccurrences = Integer.parseInt(requiredOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + requiredOccurrencesNew = iOccurrences.toString(); + } + } else { + String reqMinOccurrences = (String) titanGenericDao.getProperty(reqVertex, GraphPropertiesDictionary.MIN_OCCURRENCES.getProperty()); + if (reqMinOccurrences == null) { + reqMinOccurrences = RequirementData.MIN_OCCURRENCES; + } + if (Integer.parseInt(reqMinOccurrences) > iOccurrences) { + iOccurrences++; + requiredOccurrencesNew = iOccurrences.toString(); + } + } + } + Map<String, Object> properties = titanGenericDao.getProperties(edge); + properties.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requiredOccurrencesNew); + + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer iOccurrences = Integer.parseInt(leftOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + } + } else { + iOccurrences++; + } + leftOccurrencesNew = iOccurrences.toString(); + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + if ((associate && iOccurrences == 0) || (!associate && iOccurrences == 1)) { + // move edge to full filled state + TitanVertex outVertex = edge.outVertex(); + TitanEdge newEdge = outVertex.addEdge(requirmentNewLabel.getProperty(), reqVertex); + titanGenericDao.setProperties(newEdge, properties); + edge.remove(); + } else { + titanGenericDao.setProperties(edge, properties); + } + } else { + leftOccurrencesNew = leftOccurrences; + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + titanGenericDao.setProperties(edge, properties); + } + break; + } + } + } + } + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus updateCapabiltyEdges(GraphEdgeLabels capabiltyNewLabel, GraphEdgeLabels capabiltyCurrentLabel, RequirementAndRelationshipPair pair, String capabiltyOwnerId) { + Either<TitanVertex, TitanOperationStatus> capOwnerRI = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), capabiltyOwnerId); + if (capOwnerRI.isRight()) { + log.debug("Failed to fetch requirment Owner by Id {}. Error: {}", capabiltyOwnerId, capOwnerRI.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(capOwnerRI.right().value()); + } + Iterator<Edge> edgeIter = capOwnerRI.left().value().edges(Direction.OUT, capabiltyCurrentLabel.name(), capabiltyNewLabel.name()); + if (edgeIter == null) { + log.debug("No edges with label {} for owner RI {}", capabiltyCurrentLabel, capabiltyOwnerId); + return StorageOperationStatus.GENERAL_ERROR; + } + boolean associate = capabiltyNewLabel.equals(GraphEdgeLabels.CALCULATED_CAPABILITY_FULLFILLED) ? true : false; + + while (edgeIter.hasNext()) { + TitanEdge edge = (TitanEdge) edgeIter.next(); + TitanVertex capVertex = edge.inVertex(); + // edge.property(GraphEdgePropertiesDictionary.NAME.getProperty()).value(); + + String capabiltyId = (String) titanGenericDao.getProperty(capVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + // verify vs capability id . ( for capabilty with same name) + if (capabiltyId.equals(pair.getCapabilityUid())) { + String ownerIdOnEdge = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(pair.getCapabilityOwnerId())) { + + String requiredOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + + String requiredOccurrencesNew = "0"; + String leftOccurrencesNew = CapabilityData.MAX_OCCURRENCES; + if (requiredOccurrences != null) { + Integer iOccurrences = Integer.parseInt(requiredOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + requiredOccurrencesNew = iOccurrences.toString(); + } + } else { + String reqMinOccurrences = (String) titanGenericDao.getProperty(capVertex, GraphPropertiesDictionary.MIN_OCCURRENCES.getProperty()); + if (reqMinOccurrences == null) { + reqMinOccurrences = CapabilityData.MIN_OCCURRENCES; + } + if (Integer.parseInt(reqMinOccurrences) > iOccurrences) { + iOccurrences++; + requiredOccurrencesNew = iOccurrences.toString(); + } + } + } + Map<String, Object> properties = titanGenericDao.getProperties(edge); + properties.put(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty(), requiredOccurrencesNew); + + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer iOccurrences = Integer.parseInt(leftOccurrences); + if (associate) { + if (iOccurrences > 0) { + iOccurrences--; + } + } else { + iOccurrences++; + } + leftOccurrencesNew = iOccurrences.toString(); + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + if ((associate && iOccurrences == 0) || (!associate && iOccurrences == 1)) { + // move edge to full filled state + TitanVertex outVertex = edge.outVertex(); + TitanEdge newEdge = outVertex.addEdge(capabiltyNewLabel.getProperty(), capVertex); + titanGenericDao.setProperties(newEdge, properties); + edge.remove(); + } else { + titanGenericDao.setProperties(edge, properties); + } + } else { + properties.put(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty(), leftOccurrencesNew); + titanGenericDao.setProperties(edge, properties); + } + break; + } + } + } + return StorageOperationStatus.OK; + } + + @Override + public Either<RequirementCapabilityRelDef, StorageOperationStatus> dissociateResourceInstances(String serviceId, NodeTypeEnum nodeType, RequirementCapabilityRelDef requirementDef) { + + return dissociateResourceInstances(serviceId, nodeType, requirementDef, false); + } + + private RequirementCapabilityRelDef buildCapabilityResult(String fromResInstanceUid, String toResInstanceUid, String requirement, List<RelationshipInstData> relationshipInstDataList) { + + RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef(); + capabilityRelDef.setFromNode(fromResInstanceUid); + capabilityRelDef.setToNode(toResInstanceUid); + List<RequirementAndRelationshipPair> relationships = new ArrayList<RequirementAndRelationshipPair>(); + for (RelationshipInstData relationshipInstData : relationshipInstDataList) { + RelationshipImpl relationshipImpl = new RelationshipImpl(); + relationshipImpl.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair reqRel = new RequirementAndRelationshipPair(requirement, relationshipImpl); + capabilityRelDef.setRelationships(relationships); + reqRel.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + reqRel.setCapabilityUid(relationshipInstData.getCapabiltyId()); + reqRel.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + reqRel.setRequirementUid(relationshipInstData.getRequirementId()); + relationships.add(reqRel); + } + return capabilityRelDef; + + } + + public Either<RelationshipInstData, TitanOperationStatus> connectResourcesInService(String componentId, NodeTypeEnum nodeType, String fromResInstanceUid, String toResInstanceUid, RequirementAndRelationshipPair relationPair) { + String relationship = null; + String requirement = relationPair.getRequirement(); + if (relationPair.getRelationship() != null) { + relationship = relationPair.getRelationship().getType(); + } + + if (log.isDebugEnabled()) { + log.debug("Going to associate resource instance {} to resource instance {} under component {}. Requirement is {}.", fromResInstanceUid, toResInstanceUid, componentId, requirement); + } + + Either<ComponentInstanceData, TitanOperationStatus> fromResourceInstDataRes = findMandatoryResourceInstData(fromResInstanceUid); + if (fromResourceInstDataRes.isRight()) { + TitanOperationStatus status = fromResourceInstDataRes.right().value(); + log.error("Failed to find resource instance {}. Status is {}", fromResInstanceUid, status); + return Either.right(status); + } + ComponentInstanceData fromResourceInstanceData = fromResourceInstDataRes.left().value(); + Either<ComponentInstanceData, TitanOperationStatus> toResourceInstDataRes = findMandatoryResourceInstData(toResInstanceUid); + if (toResourceInstDataRes.isRight()) { + TitanOperationStatus status = toResourceInstDataRes.right().value(); + log.error("Failed to find resource instance " + toResInstanceUid + ". status is " + status); + return Either.right(status); + } + ComponentInstanceData toResourceInstanceData = toResourceInstDataRes.left().value(); + // THE component NodeTypeEnum should be sent + TitanOperationStatus isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, fromResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + isResourceInstOfService = verifyResourceInstanceUnderComponent(nodeType, componentId, toResInstanceUid); + if (isResourceInstOfService != TitanOperationStatus.OK) { + return Either.right(isResourceInstOfService); + } + + Either<ImmutablePair<RelationshipTypeData, String>, TitanOperationStatus> isValidRes = validateRequirementVsCapability(fromResourceInstanceData, toResourceInstanceData, requirement, relationship, relationPair); + if (isValidRes.isRight()) { + TitanOperationStatus status = isValidRes.right().value(); + log.error("Failed to validate requirement {} between resource instance {} to resource instance {}. Status is {}", requirement, fromResInstanceUid, toResInstanceUid, status); + return Either.right(status); + } + + RelationshipTypeData relationshipTypeData = isValidRes.left().value().getKey(); + String capabilityName = isValidRes.left().value().getValue(); + RelationshipInstData relationshipInstData = buildRelationshipInstData(fromResInstanceUid, requirement, relationshipTypeData, relationPair); + Either<RelationshipInstData, TitanOperationStatus> createNode = createRelationshipInstData(fromResourceInstDataRes.left().value(), relationshipInstData, relationshipTypeData, requirement); + + if (createNode.isRight()) { + return Either.right(createNode.right().value()); + } + RelationshipInstData createdRelInstData = createNode.left().value(); + Either<GraphRelation, TitanOperationStatus> associateResInst = associateRelationshipInstToTarget(toResourceInstDataRes.left().value(), requirement, capabilityName, createdRelInstData); + + if (associateResInst.isRight()) { + TitanOperationStatus status = associateResInst.right().value(); + log.error("Failed to associate relationship instance {} to target node {}. Status is {}", createdRelInstData.getUniqueId(), toResInstanceUid, status); + return Either.right(status); + } + + return Either.left(createNode.left().value()); + } + + private TitanOperationStatus verifyResourceInstanceUnderComponent(NodeTypeEnum containerNodeType, String containerComponentId, String resInstanceUid) { + + Either<ImmutablePair<ComponentMetadataData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resInstanceUid, GraphEdgeLabels.RESOURCE_INST, + containerNodeType, ComponentMetadataData.class); + + if (parentNode.isRight()) { + TitanOperationStatus status = parentNode.right().value(); + log.error("Failed to find the service associated to the resource instance {}. Status is {}", resInstanceUid, status); + return status; + } + + ImmutablePair<ComponentMetadataData, GraphEdge> componentsRes = parentNode.left().value(); + ComponentMetadataData componentMetadataData = componentsRes.getKey(); + String uniqueId = (String) componentMetadataData.getUniqueId(); + + if (containerComponentId.equals(uniqueId)) { + return TitanOperationStatus.OK; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeIncorrectServiceError, "Resource Instance - verifyResourceInstanceUnderComponent", containerComponentId); + BeEcompErrorManager.getInstance().logBeIncorrectComponentError("Resource Instance - verifyResourceInstanceUnderComponent", containerNodeType.getName(), containerComponentId); + log.debug("The provided component id {} is not equal to the component ({}) which associated to resource instance {}.", containerComponentId, uniqueId, resInstanceUid); + return TitanOperationStatus.INVALID_ID; + } + + } + + /** + * find the resource instance node in graph. + * + * @param resInstanceUid + * @return + */ + private Either<ComponentInstanceData, TitanOperationStatus> findMandatoryResourceInstData(String resInstanceUid) { + Either<ComponentInstanceData, TitanOperationStatus> resStatus = findResourceInstance(resInstanceUid); + if (resStatus.isRight()) { + TitanOperationStatus status = resStatus.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + return Either.right(status); + } + ComponentInstanceData riData = resStatus.left().value(); + return Either.left(riData); + } + + /** + * associate relationship instance node to the target resource instance node. + * + * @param toResInstance + * @param requirement + * @param relInstData + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateRelationshipInstToTarget(ComponentInstanceData toResInstance, String requirement, String capabilityName, RelationshipInstData relInstData) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(relInstData, toResInstance, GraphEdgeLabels.CAPABILITY_NODE, props); + log.debug("After creating relation between relationship instance {} to target node {}", relInstData.getUniqueId(), toResInstance.getUniqueId()); + + return createRelation; + + } + + /** + * create reslationship instance node and associate the reosurce instance node to it. + * + * @param resInstance + * @param relationshipInstData + * @param relationshipTypeData + * @param requirementName + * @return + */ + private Either<RelationshipInstData, TitanOperationStatus> createRelationshipInstData(ComponentInstanceData resInstance, RelationshipInstData relationshipInstData, RelationshipTypeData relationshipTypeData, String requirementName) { + + Either<RelationshipInstData, TitanOperationStatus> createNode = titanGenericDao.createNode(relationshipInstData, RelationshipInstData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create relationship instance node in graph. status is {}", status); + return Either.right(status); + } + + RelationshipInstData createdRelationshipInst = createNode.left().value(); + + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put("name", requirementName); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(resInstance, createdRelationshipInst, GraphEdgeLabels.RELATIONSHIP_INST, properties); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + log.error("Failed to associate resource instance " + resInstance.getUniqueIdKey() + " to relationship instance " + createdRelationshipInst.getUniqueId() + ". status is " + status); + return Either.right(status); + } + + return Either.left(createdRelationshipInst); + } + + /** + * check whether we can associate resource instances for a given requirement. + * + * 1. check the source resource instance contains the requirement + * + * 2. check the target resource instance contains a capability with the same name as the requirement + * + * @param fromResInstance + * @param toResInstance + * @param requirement + * @param relationship + * @param relationPair + * @return + */ + private Either<ImmutablePair<RelationshipTypeData, String>, TitanOperationStatus> validateRequirementVsCapability(ComponentInstanceData fromResInstance, ComponentInstanceData toResInstance, String requirement, String relationship, + RequirementAndRelationshipPair relationPair) { + + String fromResourceUid = fromResInstance.getComponentInstDataDefinition().getComponentUid(); + + String toResourceUid = toResInstance.getComponentInstDataDefinition().getComponentUid(); + Either<CapabilityDefinition, StorageOperationStatus> capabilityDefinitionE = capabilityOperation.getCapability(relationPair.getCapabilityUid(), true); + if (capabilityDefinitionE.isRight()) { + log.error("The capability cannot be found {}", relationPair.getCapabilityUid()); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + Either<RequirementDefinition, TitanOperationStatus> requirementDefinitionE = requirementOperation.getRequirement(relationPair.getRequirementUid()); + if (requirementDefinitionE.isRight()) { + log.error("The requirement cannot be found {}" , relationPair.getRequirementUid()); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + RequirementDefinition requirementDefinition = requirementDefinitionE.left().value(); + String fetchedRequirementRelationship = requirementDefinition.getRelationship(); + + String fetchedRequirementCapability = requirementDefinition.getCapability(); + // TODO temporary remove of capability sources validation - uncomment + // after alignment + // String fetchedRequirementNodeName = requirementDefinition.getNode(); + + TitanOperationStatus status = validateAvailableRequirement(fromResInstance, relationPair); + if (!status.equals(TitanOperationStatus.OK)) { + log.error("The requirement isn't available, status {}", status); + return Either.right(status); + } + status = validateAvailableCapabilty(toResInstance, relationPair); + if (!status.equals(TitanOperationStatus.OK)) { + log.error("The capabilty isn't available, status {}", status); + return Either.right(status); + } + Either<ComponentInstanceData, TitanOperationStatus> originCapabilty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), relationPair.getCapabilityOwnerId(), ComponentInstanceData.class); + if (originCapabilty.isRight()) { + log.error("Failed to fetch the origin resource for capabilty resource instance with id {}, error {}", relationPair.getCapabilityOwnerId(), originCapabilty.right().value()); + return Either.right(originCapabilty.right().value()); + } + // TODO temporary remove of capability sources validation - uncomment + // after alignment + // String originCapabId = + // originCapabilty.left().value().getComponentInstDataDefinition().getComponentUid(); + + // List<String> capabilitySources = new ArrayList<>(); + // TitanOperationStatus capabiltySourcesResult = + // resourceOperation.fillResourceDerivedListFromGraph(originCapabId, + // capabilitySources); + // if (!TitanOperationStatus.OK.equals(capabiltySourcesResult)) { + // log.error("Failed to fill capabilty cources for resource with id " + + // originCapabId + " , error " + capabiltySourcesResult); + // return Either.right(originCapabilty.right().value()); + // } + CapabilityDefinition capabilityDefinition = capabilityDefinitionE.left().value(); + String capabilityName = requirement; + + if (log.isDebugEnabled()) { + log.debug("The capability {} of resource {} appropriates to requiremt {} on resource {}", capabilityDefinition, toResourceUid, requirement, fromResourceUid); + } + String capabilityType = capabilityDefinition.getType(); + + if (false == fetchedRequirementCapability.equals(capabilityType)) { + log.error("The capability type in the requirement ({}) does not equal to the capability on the resource {}({})", fetchedRequirementCapability, toResourceUid, capabilityType); + return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + } + + // if (fetchedRequirementNodeName != null && + // !capabilitySources.contains(fetchedRequirementNodeName)) { + // log.error("The target resource instance " + toResourceUid + " is not + // of type " + fetchedRequirementNodeName); + // return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + // } + + RelationshipTypeData relationshipTypeData = new RelationshipTypeData(); + relationshipTypeData.getRelationshipTypeDataDefinition().setType(fetchedRequirementRelationship); + + ImmutablePair<RelationshipTypeData, String> result = new ImmutablePair<RelationshipTypeData, String>(relationshipTypeData, capabilityName); + return Either.left(result); + } + + private TitanOperationStatus validateAvailableRequirement(ComponentInstanceData fromResInstance, RequirementAndRelationshipPair relationPair) { + Either<TitanVertex, TitanOperationStatus> fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", fromResInstance.getUniqueId(), fromRi.right().value()); + return fromRi.right().value(); + } + Iterator<Edge> edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_REQUIREMENT.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_REQUIREMENT edges. All full filled for RI {}", fromResInstance.getUniqueId()); + return TitanOperationStatus.MATCH_NOT_FOUND; + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String reqId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement)); + if (reqId.equals(relationPair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getRequirementOwnerId())) { + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return exist ? TitanOperationStatus.OK : TitanOperationStatus.MATCH_NOT_FOUND; + } + + private TitanOperationStatus validateAvailableCapabilty(ComponentInstanceData toResInstance, RequirementAndRelationshipPair relationPair) { + Either<TitanVertex, TitanOperationStatus> fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), toResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. error {}", toResInstance.getUniqueId(), fromRi.right().value()); + return fromRi.right().value(); + } + Iterator<Edge> edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_CAPABILITY.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_CAPABILITY edges. All full filled for RI {}", toResInstance.getUniqueId()); + return TitanOperationStatus.MATCH_NOT_FOUND; + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String capId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability)); + if (capId.equals(relationPair.getCapabilityUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getCapabilityOwnerId())) { + String leftOccurrences = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return exist ? TitanOperationStatus.OK : TitanOperationStatus.NOT_FOUND; + } + + private List<ImmutablePair<String, CapabilityDefinition>> findCapabilityOfType(Map<String, CapabilityDefinition> capabilities, String fetchedRequirementCapability) { + + List<ImmutablePair<String, CapabilityDefinition>> result = new ArrayList<ImmutablePair<String, CapabilityDefinition>>(); + + if (capabilities == null) { + return null; + } + + for (Entry<String, CapabilityDefinition> entry : capabilities.entrySet()) { + CapabilityDefinition capabilityDefinition = entry.getValue(); + String type = capabilityDefinition.getType(); + if (fetchedRequirementCapability.equals(type)) { + ImmutablePair<String, CapabilityDefinition> pair = new ImmutablePair<String, CapabilityDefinition>(entry.getKey(), capabilityDefinition); + result.add(pair); + } + } + + return result; + } + + protected TitanOperationStatus validateTheTargetResourceInstance(String fetchedRequirementNodeName, String resourceUid) { + + if (fetchedRequirementNodeName == null) { + return TitanOperationStatus.OK; + } + + List<ResourceMetadataData> resourcesPathList = new ArrayList<ResourceMetadataData>(); + TitanOperationStatus status = resourceOperation.findResourcesPathRecursively(resourceUid, resourcesPathList); + if (status != TitanOperationStatus.OK) { + log.error("Failed to find the parent list of resource {}. Status is {}", resourceUid, status); + return status; + } + + boolean found = false; + if (resourcesPathList != null) { + for (ResourceMetadataData resourceData : resourcesPathList) { + String resourceName = resourceData.getMetadataDataDefinition().getName(); + if (fetchedRequirementNodeName.equals(resourceName)) { + found = true; + log.debug("The resource {} is of type {}", resourceData.getUniqueId(), fetchedRequirementNodeName); + break; + } + } + } + + if (true == found) { + return TitanOperationStatus.OK; + } else { + return TitanOperationStatus.MATCH_NOT_FOUND; + } + + } + + private RelationshipInstData buildRelationshipInstData(String fromResInstanceUid, String requirement, RelationshipTypeData relationshipTypeData, RequirementAndRelationshipPair relationPair) { + + RelationshipInstData relationshipInstData = new RelationshipInstData(); + relationshipInstData.setUniqueId(UniqueIdBuilder.buildRelationsipInstInstanceUid(fromResInstanceUid, requirement)); + String type = null; + if (relationshipTypeData != null) { + type = relationshipTypeData.getRelationshipTypeDataDefinition().getType(); + } + + relationshipInstData.setType(type); + Long creationDate = System.currentTimeMillis(); + relationshipInstData.setCreationTime(creationDate); + relationshipInstData.setModificationTime(creationDate); + relationshipInstData.setCapabilityOwnerId(relationPair.getCapabilityOwnerId()); + relationshipInstData.setRequirementOwnerId(relationPair.getRequirementOwnerId()); + relationshipInstData.setCapabiltyId(relationPair.getCapabilityUid()); + relationshipInstData.setRequirementId(relationPair.getRequirementUid()); + + return relationshipInstData; + } + + private Either<ComponentInstanceData, TitanOperationStatus> findResourceInstance(String resInstanceUid) { + + Either<ComponentInstanceData, TitanOperationStatus> node = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resInstanceUid, ComponentInstanceData.class); + + return node; + + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> updateResourceInstance(String serviceId, NodeTypeEnum nodeType, String resourceInstanceUid, ComponentInstance resourceInstance, boolean inTransaction) { + + Either<ComponentInstance, StorageOperationStatus> result = null; + try { + + Either<ComponentInstance, TitanOperationStatus> updateRes = updateResourceInstanceInService(serviceId, resourceInstanceUid, resourceInstance); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to update resource instance {}. Status is {}", resourceInstanceUid, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ComponentInstance value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + /** + * prepare new resource instance object for update + * + * @param resourceInstance + * @param currentInst + * @return + */ + private ComponentInstance normalizeResourceInstanceForUpdate(ComponentInstance resourceInstance, ComponentInstanceData currentInst) { + + ComponentInstance instance = new ComponentInstance(); + instance.setUniqueId((String) currentInst.getUniqueId()); + Long modificationTime = resourceInstance.getModificationTime(); + if (modificationTime == null) { + modificationTime = System.currentTimeMillis(); + } + instance.setModificationTime(modificationTime); + instance.setPosX(resourceInstance.getPosX()); + instance.setPosY(resourceInstance.getPosY()); + instance.setDescription(resourceInstance.getDescription()); + instance.setName(resourceInstance.getName()); + instance.setNormalizedName(resourceInstance.getNormalizedName()); + instance.setPropertyValueCounter(resourceInstance.getPropertyValueCounter()); + instance.setAttributeValueCounter(resourceInstance.getAttributeValueCounter()); + instance.setInputValueCounter(resourceInstance.getInputValueCounter()); + return instance; + } + + private void printDiff(ComponentInstanceData currentInst, ComponentInstance resourceInstance) { + + log.debug("The current Resource Instance details are : {}", currentInst); + log.debug("The received Resource Instance details for update are : {}", resourceInstance); + + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> updateResourceInstance(String serviceId, NodeTypeEnum nodeType, String resourceInstanceName, ComponentInstance resourceInstance) { + + return updateResourceInstance(serviceId, nodeType, resourceInstanceName, resourceInstance, false); + } + + public Either<ComponentInstance, TitanOperationStatus> updateResourceInstanceInService(String serviceId, String resourceInstanceUid, ComponentInstance resourceInstance) { + + log.debug("Going to update resource instance {}. Properties are {}", resourceInstanceUid, resourceInstance); + Either<ComponentInstanceData, TitanOperationStatus> findInstRes = findResourceInstance(resourceInstanceUid); + if (findInstRes.isRight()) { + TitanOperationStatus status = findInstRes.right().value(); + log.error("Failed to find resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + + ComponentInstanceData currentInst = findInstRes.left().value(); + if (log.isDebugEnabled()) { + printDiff(currentInst, resourceInstance); + } + + ComponentInstance resourceInstanceForUpdate = normalizeResourceInstanceForUpdate(resourceInstance, currentInst); + + ComponentInstanceData resourceInstanceData = new ComponentInstanceData(resourceInstanceForUpdate); + + Either<ComponentInstanceData, TitanOperationStatus> updateNodeRes = titanGenericDao.updateNode(resourceInstanceData, ComponentInstanceData.class); + if (updateNodeRes.isRight()) { + TitanOperationStatus status = updateNodeRes.right().value(); + log.error("Failed to update resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + + ComponentInstanceData value = updateNodeRes.left().value(); + + ComponentInstance instance = new ComponentInstance(value.getComponentInstDataDefinition()); + + return Either.left(instance); + + } + + @Override + public Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, StorageOperationStatus> getAllComponentInstances(String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType, boolean inTransaction) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, StorageOperationStatus> result = null; + + try { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> resInstancesOfService = getComponentInstancesOfComponent(componentId, containerNodeType, compInstNodeType); + + log.trace("After fetching resource instances of component {}. result is {}", componentId, resInstancesOfService); + if (resInstancesOfService.isRight()) { + TitanOperationStatus status = resInstancesOfService.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find resource instances of service {}. Status is {}", componentId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>> immutablePair = resInstancesOfService.left().value(); + List<ComponentInstance> nodes = immutablePair.getKey(); + if (nodes == null || nodes.isEmpty()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + result = Either.left(immutablePair); + return result; + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + @Override + public Either<Boolean, StorageOperationStatus> isComponentInstanceNameExist(String parentComponentId, NodeTypeEnum nodeType, String compInstId, String componentInstName) { + + Either<Boolean, StorageOperationStatus> result = null; + Either<Boolean, TitanOperationStatus> updateRes = isComponentInstanceNameExistOnGraph(parentComponentId, nodeType, compInstId, componentInstName); + + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + log.error("Failed to find component instance name {}. Status is {}", componentInstName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Boolean value = updateRes.left().value(); + + result = Either.left(value); + + return result; + + } + + private Either<Boolean, TitanOperationStatus> isComponentInstanceNameExistOnGraph(String parentComponentId, NodeTypeEnum parentNodeType, String compInstId, String componentInstName) { + + Either<TitanGraph, TitanOperationStatus> graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.debug("Failed to retrieve graph. status is {}", graphRes); + return Either.right(graphRes.right().value()); + } + + TitanGraph titanGraph = graphRes.left().value(); + Iterable<TitanVertex> vertices = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentComponentId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + + TitanVertex serviceVertex = vertices.iterator().next(); + TitanVertexQuery query = serviceVertex.query(); + query = query.labels(GraphEdgeLabels.RESOURCE_INST.getProperty()); + Iterable<Vertex> verts = query.vertices(); + if (verts == null) { + log.debug("No edges in graph for criteria"); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + Iterator<Vertex> vIter = verts.iterator(); + while (vIter.hasNext()) { + Vertex vert = vIter.next(); + String resInstName = vert.value(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty()); + if (resInstName.equals(componentInstName)) { + if (compInstId != null) {// will be null if we got here from + // create + // Update case - skipping if this is the same component + // instance we are updating, that is allowing + // update of the unchanged name on a component instance. + // This is needed to support position only update, since + // name should + // always be passed in update, and in position case, the + // name will be unchanged. + String uniqueId = vert.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + if (uniqueId.equals(compInstId)) { + continue; + } + } + return Either.left(Boolean.TRUE); + } + } + return Either.left(Boolean.FALSE); + } + + /** + * find resource instances and the relationships between the relationships of a given resource + * + * @param componentId + * @return + */ + public Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> getComponentInstancesOfComponent(String componentId, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + if (log.isDebugEnabled()) + log.debug("Going to fetch all resource instances under component {}", componentId); + + Either<ComponentMetadataData, TitanOperationStatus> componentRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentId, ComponentMetadataData.class); + if (componentRes.isRight()) { + TitanOperationStatus status = componentRes.right().value(); + log.error("Failed to find component {}. Status is {}", componentId, status); + return Either.right(status); + } + + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(componentId, containerNodeType, true); + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("Resource instance was found under component {}. status is {}", componentId, status); + return Either.right(status); + } + + List<ComponentInstance> resourcesResult = new ArrayList<ComponentInstance>(); + List<RequirementCapabilityRelDef> requirementsResult = new ArrayList<RequirementCapabilityRelDef>(); + + List<ImmutablePair<ComponentInstanceData, GraphEdge>> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + Map<String, Map<String, CapabilityDefinition>> compInstCapabilities = new HashMap<String, Map<String, CapabilityDefinition>>(); + Map<String, Map<String, RequirementDefinition>> compInstReq = new HashMap<String, Map<String, RequirementDefinition>>(); + Map<String, Map<String, ArtifactDefinition>> compInstArtifacts = new HashMap<String, Map<String, ArtifactDefinition>>(); + Map<String, Component> compInstOriginsMap = new HashMap<String, Component>(); + + for (ImmutablePair<ComponentInstanceData, GraphEdge> immutablePair : resourceInstances) { + + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + if (log.isDebugEnabled()) + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + + ComponentInstance resourceInstance = new ComponentInstance(resourceInstanceData.getComponentInstDataDefinition()); + + TitanOperationStatus status = getFullComponentInstance(compInstCapabilities, compInstReq, compInstArtifacts, compInstOriginsMap, resourceInstance, compInstNodeType); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + resourcesResult.add(resourceInstance); + + Either<List<ImmutablePair<RelationshipInstData, GraphEdge>>, TitanOperationStatus> relationshipsRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), + (String) resourceInstanceData.getUniqueId(), GraphEdgeLabels.RELATIONSHIP_INST, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {} under component {} . status is {}", resourceInstanceData.getUniqueId(), componentId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + continue; + } else { + log.error("Failed to find relationhips of resource instance {} under component {}. status is {}", resourceInstanceData.getUniqueId(), componentId, status); + return Either.right(status); + } + } + + String sourceResourceUid = (String) resourceInstanceData.getUniqueId(); + + Map<String, List<ImmutablePair<String, RelationshipInstData>>> targetNodeToRelationship = new HashMap<String, List<ImmutablePair<String, RelationshipInstData>>>(); + + List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipsImpl = relationshipsRes.left().value(); + status = populateTargetAndRelationsForGivenSource(targetNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (targetNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForSource(requirementsResult, sourceResourceUid, targetNodeToRelationship); + + } + + return Either.left(new ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>(resourcesResult, requirementsResult)); + } else { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + } + + private Either<List<RequirementCapabilityRelDef>, TitanOperationStatus> getRelationsForSource(String resourceInstanceUid) { + Either<List<ImmutablePair<RelationshipInstData, GraphEdge>>, TitanOperationStatus> relationshipsRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, + GraphEdgeLabels.RELATIONSHIP_INST, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + TitanOperationStatus status; + List<RequirementCapabilityRelDef> requirementsResult = new ArrayList<RequirementCapabilityRelDef>(); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {}. Status is {}", resourceInstanceUid, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(requirementsResult); + } else { + log.error("Failed to find relationhips of resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + } + + Map<String, List<ImmutablePair<String, RelationshipInstData>>> targetNodeToRelationship = new HashMap<String, List<ImmutablePair<String, RelationshipInstData>>>(); + + List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipsImpl = relationshipsRes.left().value(); + status = populateTargetAndRelationsForGivenSource(targetNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (targetNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceUid); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForSource(requirementsResult, resourceInstanceUid, targetNodeToRelationship); + return Either.left(requirementsResult); + } + + private Either<List<RequirementCapabilityRelDef>, TitanOperationStatus> getRelationsForTarget(String resourceInstanceUid) { + + TitanOperationStatus status; + + Either<List<ImmutablePair<RelationshipInstData, GraphEdge>>, TitanOperationStatus> relationshipsRes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceUid, + GraphEdgeLabels.CAPABILITY_NODE, NodeTypeEnum.RelationshipInst, RelationshipInstData.class); + + List<RequirementCapabilityRelDef> requirementsResult = new ArrayList<RequirementCapabilityRelDef>(); + + if (relationshipsRes.isRight()) { + status = relationshipsRes.right().value(); + log.debug("After fetching all reslationships of resource instance {}. Status is {}", resourceInstanceUid, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(requirementsResult); + } else { + log.error("Failed to find relationhips of resource instance {}. Status is {}", resourceInstanceUid, status); + return Either.right(status); + } + } + + Map<String, List<ImmutablePair<String, RelationshipInstData>>> sourceNodeToRelationship = new HashMap<String, List<ImmutablePair<String, RelationshipInstData>>>(); + + List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipsImpl = relationshipsRes.left().value(); + status = populateSourceAndRelationsForGivenTarget(sourceNodeToRelationship, relationshipsImpl); + + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + if (sourceNodeToRelationship.isEmpty()) { + log.error("No target found for relationship instances of resource instance {}", resourceInstanceUid); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + buildRelationsForTarget(requirementsResult, resourceInstanceUid, sourceNodeToRelationship); + return Either.left(requirementsResult); + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> getFullComponentInstance(ComponentInstance componentInstance, NodeTypeEnum compInstNodeType) { + Map<String, Map<String, CapabilityDefinition>> compInstCapabilities = new HashMap<String, Map<String, CapabilityDefinition>>(); + Map<String, Map<String, RequirementDefinition>> compInstReq = new HashMap<String, Map<String, RequirementDefinition>>(); + Map<String, Map<String, ArtifactDefinition>> compInstArtifacts = new HashMap<String, Map<String, ArtifactDefinition>>(); + Map<String, Component> compInstOrigins = new HashMap<String, Component>(); + + TitanOperationStatus fullResourceInstance = getFullComponentInstance(compInstCapabilities, compInstReq, compInstArtifacts, compInstOrigins, componentInstance, compInstNodeType); + if (!fullResourceInstance.equals(TitanOperationStatus.OK)) { + log.debug("failed to get full data of resource instance. error: {}", fullResourceInstance); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(fullResourceInstance)); + } + return Either.left(componentInstance); + } + + private TitanOperationStatus getFullComponentInstance(Map<String, Map<String, CapabilityDefinition>> compInstCapabilities, Map<String, Map<String, RequirementDefinition>> compInstReq, + Map<String, Map<String, ArtifactDefinition>> compInstArtifacts, Map<String, Component> compInstOrigins, ComponentInstance compInst, NodeTypeEnum compInstNodeType) { + Component component = null; + ComponentOperation componentOperation = getComponentOperation(compInstNodeType); + String componentUid = compInst.getComponentUid(); + if (compInstOrigins.containsKey(componentUid)) { + component = compInstOrigins.get(componentUid); + } else { + Either<Component, StorageOperationStatus> metadataComponent = componentOperation.getMetadataComponent(componentUid, true); + if (metadataComponent.isRight()) { + log.debug("Failed to fetch the origin component for component instance, origin Id {}, error: {}", componentUid, metadataComponent.right().value()); + return TitanOperationStatus.GENERAL_ERROR; + } + component = metadataComponent.left().value(); + compInstOrigins.put(componentUid, component); + + } + String icon = component.getIcon(); + if (log.isDebugEnabled()) + log.debug("Fetch the resource instance icon from the resource itself. icon = {}", icon); + compInst.setIcon(icon); + String componentName = component.getName(); + compInst.setComponentName(componentName); + compInst.setComponentVersion(component.getVersion()); + if (component.getComponentType() == ComponentTypeEnum.RESOURCE) { + compInst.setToscaComponentName(((Resource) component).getToscaResourceName()); + } + + List<ComponentInstance> componentInstances = new ArrayList<>(); + List<String> derivedFromList = new ArrayList<String>(); + + // For VFC/VL/CP + if (compInstNodeType == NodeTypeEnum.Resource && ((Resource) component).getResourceType() != ResourceTypeEnum.VF) { + resourceOperation.fillResourceDerivedListFromGraph(component.getUniqueId(), derivedFromList); + } else { + // Getting component instances that the origin component of this + // component instance is their container, so we can use the logic of + // getting req/cap from them + // and fill this component instance with those req/cap + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> allComponentInstanceFromGraph = getAllComponentInstanceFromGraph(componentUid, compInstNodeType, true); + if (allComponentInstanceFromGraph.isRight() && allComponentInstanceFromGraph.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Couldn't fetch component instances for component {} of type {}", componentUid, compInstNodeType); + return allComponentInstanceFromGraph.right().value(); + } + List<ImmutablePair<ComponentInstanceData, GraphEdge>> allCIs = allComponentInstanceFromGraph.isLeft() ? allComponentInstanceFromGraph.left().value() : new ArrayList<>(); + for (ImmutablePair<ComponentInstanceData, GraphEdge> entry : allCIs) { + componentInstances.add(new ComponentInstance(entry.left.getComponentInstDataDefinition())); + } + component.setComponentInstances(componentInstances); + } + + StorageOperationStatus capStatus = setCompInstCapabilitiesFromGraph(compInstCapabilities, component, compInstNodeType, compInst, derivedFromList); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find capability of resource {}. status is {}", componentName, capStatus); + + } + capStatus = setCompInstRequirementsFromGraph(compInstReq, component, compInstNodeType, compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find requirements of resource {}. status is {}", componentName, capStatus); + + } + + capStatus = setCompInstDeploymentArtifactsFromGraph(compInstArtifacts, componentUid, compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find resource deployment artifacts of resource {}. status is {}", componentName, capStatus); + + } + + capStatus = setCompInstArtifactsFromGraph(compInst); + if (capStatus != StorageOperationStatus.OK) { + log.debug("Failed to find resource deployment artifacts of resource instance {} . status is {}", compInst.getName(), capStatus); + } + return TitanOperationStatus.OK; + } + + protected StorageOperationStatus setCompInstArtifactsFromGraph(ComponentInstance resourceInstance) { + + Map<String, ArtifactDefinition> deploymentArtifacts = null; + if (resourceInstance.getDeploymentArtifacts() == null) { + deploymentArtifacts = new HashMap<String, ArtifactDefinition>(); + } else { + deploymentArtifacts = new HashMap<String, ArtifactDefinition>(resourceInstance.getDeploymentArtifacts()); + } + + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = artifactOperation.getArtifacts(resourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + return status; + } else { + resourceInstance.setDeploymentArtifacts(deploymentArtifacts); + return StorageOperationStatus.OK; + } + } + + Map<String, ArtifactDefinition> artifacts = result.left().value(); + if ((artifacts != null) && !artifacts.isEmpty()) { + for (ArtifactDefinition artifact : artifacts.values()) { + if (artifact.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())) { + Either<List<HeatParameterDefinition>, StorageOperationStatus> heatParamsForEnv = artifactOperation.getHeatParamsForEnv(artifact); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", artifact.getUniqueId()); + return heatParamsForEnv.right().value(); + } else { + artifact.setHeatParameters(heatParamsForEnv.left().value()); + } + } + } + + // add resource instance artifacts to the artifacts inherited from + // resource + deploymentArtifacts.putAll(artifacts); + resourceInstance.setDeploymentArtifacts(deploymentArtifacts); + } + + return StorageOperationStatus.OK; + + } + + // resourceInstance) { + // ArrayList<HeatParameterDefinition>(); + // heatEnvArtifact.getGeneratedFromId()); + // Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, + // TitanOperationStatus> heatEnvValuesWithEdges = titanGenericDao + // !heatEnvValuesWithEdges.right().value().equals(TitanOperationStatus.NOT_FOUND)) + // { + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // heatEnvValuesWithEdges.left().value()){ + // pair.right.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + // heatValuesMap.get(parameter.getName()); + private Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> getAllComponentInstanceFromGraph(String componentId, NodeTypeEnum containerNodeType, boolean withEdges) { + if (log.isDebugEnabled()) + log.debug("Going to fetch all resource instances nodes in graph associate to component {}", componentId); + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(containerNodeType), componentId, GraphEdgeLabels.RESOURCE_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class, withEdges); + if (log.isDebugEnabled()) + log.debug("After fetching all component instances under component {}", componentId); + + if (resourceInstancesRes.isLeft()) { + printAllResourceInstancesNames(resourceInstancesRes); + } + return resourceInstancesRes; + } + + private void printAllResourceInstancesNames(Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes) { + if (log.isTraceEnabled()) { + StringBuilder builder = new StringBuilder(); + builder.append("Result is "); + List<ImmutablePair<ComponentInstanceData, GraphEdge>> listResData = resourceInstancesRes.left().value(); + for (ImmutablePair<ComponentInstanceData, GraphEdge> resInstPair : listResData) { + ComponentInstanceData resdata = resInstPair.getLeft(); + builder.append(resdata.getName()).append(", "); + } + log.trace(builder.toString()); + } + } + + private TitanOperationStatus populateTargetAndRelationsForGivenSource(Map<String, List<ImmutablePair<String, RelationshipInstData>>> targetNodeToRelationship, List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipsImpl) { + if (relationshipsImpl != null && false == relationshipsImpl.isEmpty()) { + for (ImmutablePair<RelationshipInstData, GraphEdge> pair : relationshipsImpl) { + RelationshipInstData relationshipInstData = pair.getKey(); + + GraphEdge requirementEdge = pair.getValue(); + String requirementName = (String) requirementEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + + Either<ImmutablePair<ComponentInstanceData, GraphEdge>, TitanOperationStatus> targetNodeRes = titanGenericDao.getChild(relationshipInstData.getUniqueIdKey(), relationshipInstData.getUniqueId(), GraphEdgeLabels.CAPABILITY_NODE, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (targetNodeRes.isRight()) { + TitanOperationStatus status = targetNodeRes.right().value(); + log.error("Failed to find the target node of relationship inst {}. Status is {}", relationshipInstData, status); + return status; + } + + addRelationshipInstToTargetMap(targetNodeToRelationship, relationshipInstData, requirementName, targetNodeRes); + + } + } + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus populateSourceAndRelationsForGivenTarget(Map<String, List<ImmutablePair<String, RelationshipInstData>>> sourceNodeToRelationship, List<ImmutablePair<RelationshipInstData, GraphEdge>> relationshipsImpl) { + if (relationshipsImpl != null && false == relationshipsImpl.isEmpty()) { + for (ImmutablePair<RelationshipInstData, GraphEdge> pair : relationshipsImpl) { + RelationshipInstData relationshipInstData = pair.getKey(); + + GraphEdge requirementEdge = pair.getValue(); + String requirementName = (String) requirementEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + + Either<ImmutablePair<ComponentInstanceData, GraphEdge>, TitanOperationStatus> sourceNodeRes = titanGenericDao.getParentNode(relationshipInstData.getUniqueIdKey(), relationshipInstData.getUniqueId(), GraphEdgeLabels.RELATIONSHIP_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (sourceNodeRes.isRight()) { + TitanOperationStatus status = sourceNodeRes.right().value(); + log.error("Failed to find the source node of relationship inst {}. Status is {}", relationshipInstData, status); + return status; + } + + addRelationshipInstToTargetMap(sourceNodeToRelationship, relationshipInstData, requirementName, sourceNodeRes); + + } + } + + return TitanOperationStatus.OK; + } + + private void buildRelationsForSource(List<RequirementCapabilityRelDef> requirementsResult, String sourceResourceUid, Map<String, List<ImmutablePair<String, RelationshipInstData>>> targetNodeToRelationship) { + for (Entry<String, List<ImmutablePair<String, RelationshipInstData>>> targetToRel : targetNodeToRelationship.entrySet()) { + RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef(); + requirementCapabilityRelDef.setFromNode(sourceResourceUid); + String targetUid = targetToRel.getKey(); + requirementCapabilityRelDef.setToNode(targetUid); + + List<RequirementAndRelationshipPair> relationships = new ArrayList<RequirementAndRelationshipPair>(); + + populateRelationships(targetToRel, relationships); + requirementCapabilityRelDef.setRelationships(relationships); + + requirementsResult.add(requirementCapabilityRelDef); + } + } + + private void buildRelationsForTarget(List<RequirementCapabilityRelDef> requirementsResult, String targetResourceUid, Map<String, List<ImmutablePair<String, RelationshipInstData>>> sourceNodeToRelationship) { + for (Entry<String, List<ImmutablePair<String, RelationshipInstData>>> sourceToRel : sourceNodeToRelationship.entrySet()) { + RequirementCapabilityRelDef requirementCapabilityRelDef = new RequirementCapabilityRelDef(); + requirementCapabilityRelDef.setToNode(targetResourceUid); + String sourceUid = sourceToRel.getKey(); + requirementCapabilityRelDef.setFromNode(sourceUid); + + List<RequirementAndRelationshipPair> relationships = new ArrayList<RequirementAndRelationshipPair>(); + + populateRelationships(sourceToRel, relationships); + requirementCapabilityRelDef.setRelationships(relationships); + + requirementsResult.add(requirementCapabilityRelDef); + } + } + + private void addRelationshipInstToTargetMap(Map<String, List<ImmutablePair<String, RelationshipInstData>>> targetNodeToRelationship, RelationshipInstData relationshipInstData, String requirementName, + Either<ImmutablePair<ComponentInstanceData, GraphEdge>, TitanOperationStatus> targetNodeRes) { + + ImmutablePair<ComponentInstanceData, GraphEdge> targetResourcePair = targetNodeRes.left().value(); + ComponentInstanceData targetResourceData = targetResourcePair.getKey(); + + GraphEdge edge = targetResourcePair.right; + if (edge.getEdgeType().equals(GraphEdgeLabels.RELATIONSHIP_INST)) { + requirementName = (String) edge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + } + + String targetResourceUid = (String) targetResourceData.getUniqueId(); + List<ImmutablePair<String, RelationshipInstData>> requirementRelationshipPair = targetNodeToRelationship.get(targetResourceUid); + if (requirementRelationshipPair == null) { + requirementRelationshipPair = new ArrayList<ImmutablePair<String, RelationshipInstData>>(); + targetNodeToRelationship.put(targetResourceUid, requirementRelationshipPair); + } + ImmutablePair<String, RelationshipInstData> reqRelationshipPair = new ImmutablePair<String, RelationshipInstData>(requirementName, relationshipInstData); + requirementRelationshipPair.add(reqRelationshipPair); + } + + private void populateRelationships(Entry<String, List<ImmutablePair<String, RelationshipInstData>>> targetToRel, List<RequirementAndRelationshipPair> relationships) { + + List<ImmutablePair<String, RelationshipInstData>> values = targetToRel.getValue(); + for (ImmutablePair<String, RelationshipInstData> value : values) { + String reqName = value.getKey(); + RelationshipInstData relationshipInstData = value.getValue(); + RelationshipImpl relationshipImpl = new RelationshipImpl(); + relationshipImpl.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(reqName, relationshipImpl); + pair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + pair.setCapabilityUid(relationshipInstData.getCapabiltyId()); + pair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + pair.setRequirementUid(relationshipInstData.getRequirementId()); + relationships.add(pair); + } + } + + /** + * FOR TEST ONLY + * + * @param resourceOperation + */ + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + @Override + public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation, boolean inTransaction) { + + Either<RequirementCapabilityRelDef, StorageOperationStatus> result = null; + try { + Either<RequirementCapabilityRelDef, TitanOperationStatus> multiRequirements = associateResourceInstancesMultiRequirements(componentId, nodeType, relation); + if (multiRequirements.isRight()) { + TitanOperationStatus status = multiRequirements.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "associateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("associateComponentInstances"); + log.debug("Failed to associate component instances. {}. Status is {}", relation, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + StorageOperationStatus updateCalculatedCapReqResult = updateCalculatedCapReq(relation, true); + if (!updateCalculatedCapReqResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "associateComponentInstances"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("associateComponentInstances"); + log.debug("Failed to associate component instances. {}. Status is {}", relation, updateCalculatedCapReqResult); + result = Either.right(updateCalculatedCapReqResult); + return result; + } + result = Either.left(multiRequirements.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + } + + private Either<RequirementCapabilityRelDef, TitanOperationStatus> associateResourceInstancesMultiRequirements(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation) { + + String fromNode = relation.getFromNode(); + String toNode = relation.getToNode(); + List<RequirementAndRelationshipPair> relationships = relation.getRelationships(); + if (relationships == null || relationships.isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedAddingResourceInstanceError, "AssociateResourceInstances - missing relationship", fromNode, componentId); + BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId); + log.debug("No requirement definition sent in order to set the relation between {} to {}", fromNode, toNode); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + List<RequirementAndRelationshipPair> relationshipsResult = new ArrayList<RequirementAndRelationshipPair>(); + for (RequirementAndRelationshipPair immutablePair : relationships) { + String requirement = immutablePair.getRequirement(); + + Either<RelationshipInstData, TitanOperationStatus> associateRes = connectResourcesInService(componentId, nodeType, fromNode, toNode, immutablePair); + + if (associateRes.isRight()) { + TitanOperationStatus status = associateRes.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedAddingResourceInstanceError, "AssociateResourceInstances", fromNode, componentId); + BeEcompErrorManager.getInstance().logBeFailedAddingResourceInstanceError("AssociateResourceInstances - missing relationship", fromNode, componentId); + log.debug("Failed to associate resource instance {} to resource instnace {}. Status is {}", fromNode, toNode, status); + return Either.right(status); + } + + RelationshipInstData relationshipInstData = associateRes.left().value(); + RelationshipImpl relationshipImplResult = new RelationshipImpl(); + relationshipImplResult.setType(relationshipInstData.getType()); + RequirementAndRelationshipPair requirementAndRelationshipPair = new RequirementAndRelationshipPair(requirement, relationshipImplResult); + requirementAndRelationshipPair.setCapability(immutablePair.getCapability()); + requirementAndRelationshipPair.setCapabilityOwnerId(relationshipInstData.getCapabilityOwnerId()); + requirementAndRelationshipPair.setRequirementOwnerId(relationshipInstData.getRequirementOwnerId()); + requirementAndRelationshipPair.setCapabilityUid(immutablePair.getCapabilityUid()); + requirementAndRelationshipPair.setRequirementUid(immutablePair.getRequirementUid()); + relationshipsResult.add(requirementAndRelationshipPair); + + } + + RequirementCapabilityRelDef capabilityRelDef = new RequirementCapabilityRelDef(); + capabilityRelDef.setFromNode(fromNode); + capabilityRelDef.setToNode(toNode); + capabilityRelDef.setRelationships(relationshipsResult); + + return Either.left(capabilityRelDef); + } + + @Override + public Either<RequirementCapabilityRelDef, StorageOperationStatus> associateResourceInstances(String componentId, NodeTypeEnum nodeType, RequirementCapabilityRelDef relation) { + return associateResourceInstances(componentId, nodeType, relation, false); + } + + @Override + public Either<List<ComponentInstance>, StorageOperationStatus> deleteAllComponentInstances(String containerComponentId, NodeTypeEnum containerNodeType, boolean inTransaction) { + + Either<List<ComponentInstance>, StorageOperationStatus> result = null; + try { + Either<List<ComponentInstance>, TitanOperationStatus> multiRequirements = deleteAllComponentInstancesInternal(containerComponentId, containerNodeType); + if (multiRequirements.isRight()) { + TitanOperationStatus status = multiRequirements.right().value(); + if (multiRequirements.right().value() != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "deleteAllResourceInstances - missing relationship"); + BeEcompErrorManager.getInstance().logBeSystemError("deleteAllResourceInstances - missing relationship"); + } + log.debug("Failed to delete resource instances of service {}. Status is {}", containerComponentId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + + result = Either.left(multiRequirements.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + + } + + @Override + public Either<List<ComponentInstance>, StorageOperationStatus> deleteAllComponentInstances(String containerComponentId, NodeTypeEnum nodeType) { + return deleteAllComponentInstances(containerComponentId, nodeType, false); + } + + public Either<List<ComponentInstance>, TitanOperationStatus> deleteAllComponentInstancesInternal(String componentId, NodeTypeEnum nodeType) { + + log.debug("Going to delete all resource instances and their relatioships from service {}", componentId); + + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, GraphEdgeLabels.RESOURCE_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("After fetching all resource instances of service {}. Status is {}", componentId, status); + return Either.right(status); + } + + List<ComponentInstance> result = new ArrayList<ComponentInstance>(); + List<ImmutablePair<ComponentInstanceData, GraphEdge>> listOfResInstances = resourceInstancesRes.left().value(); + for (ImmutablePair<ComponentInstanceData, GraphEdge> resInstance : listOfResInstances) { + ComponentInstanceData resourceInstanceData = resInstance.getKey(); + String resourceInstUid = resourceInstanceData.getUniqueId(); + Either<ComponentInstance, TitanOperationStatus> removeResourceInstanceRes = removeComponentInstanceFromComponent(nodeType, componentId, resourceInstUid); + log.debug("After removing resource instance {}. Result is {}", resourceInstUid, removeResourceInstanceRes); + if (removeResourceInstanceRes.isRight()) { + TitanOperationStatus status = removeResourceInstanceRes.right().value(); + log.error("After removing resource instance {}. Status is {}", resourceInstUid, status); + return Either.right(status); + } + ComponentInstance resourceInstance = removeResourceInstanceRes.left().value(); + result.add(resourceInstance); + } + + log.debug("The following resource instances was deleted from service {}:{}", componentId, result); + + return Either.left(result); + } + + public Either<ImmutablePair<List<ComponentInstance>, Map<String, String>>, StorageOperationStatus> cloneAllComponentInstancesFromContainerComponent(String componentIdFrom, Component component, NodeTypeEnum containerNodeType, + NodeTypeEnum compInstNodeType, LifecycleStateEnum targetLifecycle, Map<String, List<ComponentInstanceInput>> inputsValuesMap) { + + List<ComponentInstance> list = new ArrayList<ComponentInstance>(); + Map<String, String> oldCompInstToNew = new HashMap<>(); + + ImmutablePair<List<ComponentInstance>, Map<String, String>> result = new ImmutablePair<List<ComponentInstance>, Map<String, String>>(list, oldCompInstToNew); + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, StorageOperationStatus> allResourceInstances = getAllComponentInstances(componentIdFrom, containerNodeType, compInstNodeType, true); + + if (allResourceInstances.isRight()) { + StorageOperationStatus status = allResourceInstances.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + + return Either.left(result); + } else { + log.error("failed to get all resource instances for service {}. status={}", componentIdFrom, status); + return Either.right(status); + } + } + + List<ComponentInstance> riList = allResourceInstances.left().value().left; + Map<String, ComponentInstance> riMapper = new HashMap<>(); + int instanceNumber = 0; + for (ComponentInstance ri : riList) { + instanceNumber++; + String origRiUniqueID = ri.getUniqueId(); + Either<ComponentInstance, StorageOperationStatus> createResourceInstance = createComponentInstance(component.getUniqueId(), containerNodeType, String.valueOf(instanceNumber), false, ri, compInstNodeType, true, true); + if (createResourceInstance.isRight()) { + StorageOperationStatus status = createResourceInstance.right().value(); + log.error("failed to clone resource instance {}. status ={}", origRiUniqueID, status); + return Either.right(status); + } + ComponentInstance createdInstance = createResourceInstance.left().value(); + riMapper.put(origRiUniqueID, createdInstance); + StorageOperationStatus associateArtifactsToResource = cloneResourceInstanceArtifacts(createdInstance, ri, targetLifecycle); + if (associateArtifactsToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} artifacts. error {} ", ri.getNormalizedName(), associateArtifactsToResource.name()); + return Either.right(associateArtifactsToResource); + } + + StorageOperationStatus associatePropertyValuesToResource = cloneResourceInstancePropertyValues(createdInstance, ri); + if (associatePropertyValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + + StorageOperationStatus associateAttributeValuesToResource = cloneResourceInstanceAttributeValues(createdInstance, ri); + if (associateAttributeValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} attribute values. error {} ", ri.getNormalizedName(), associateAttributeValuesToResource.name()); + return Either.right(associateAttributeValuesToResource); + } + + StorageOperationStatus associateInputValuesToResource = cloneResourceInstanceInputsValues(createdInstance, ri, component, inputsValuesMap); + if (associateInputValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + + list.add(createdInstance); + oldCompInstToNew.put(origRiUniqueID, createdInstance.getUniqueId()); + } + + List<RequirementCapabilityRelDef> relationsList = allResourceInstances.left().value().right; + for (RequirementCapabilityRelDef relation : relationsList) { + String origFrom = relation.getFromNode(); + String origTo = relation.getToNode(); + relation.setFromNode(riMapper.get(origFrom).getUniqueId()); + relation.setToNode(riMapper.get(origTo).getUniqueId()); + List<RequirementAndRelationshipPair> relationships = relation.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + // for all atomic resource instances need to update to relevant + // new ri ids + String capOwnerId = pair.getCapabilityOwnerId(); + String reqOwnerId = pair.getRequirementOwnerId(); + if (isAtomicComponentInstance(riMapper.get(origFrom))) { + reqOwnerId = riMapper.get(reqOwnerId).getUniqueId(); + } + if (isAtomicComponentInstance(riMapper.get(origTo))) { + capOwnerId = riMapper.get(capOwnerId).getUniqueId(); + } + pair.setRequirementOwnerId(reqOwnerId); + pair.setCapabilityOwnerId(capOwnerId); + } + + Either<RequirementCapabilityRelDef, StorageOperationStatus> associateInstances = associateResourceInstances(component.getUniqueId(), containerNodeType, relation, true); + if (associateInstances.isRight()) { + StorageOperationStatus status = associateInstances.right().value(); + log.error("failed to assosiate resource instance {} and resource instance {}. status ={}", relation.getFromNode(), relation.getToNode(), status); + return Either.right(status); + } + } + + return Either.left(result); + } + + public Either<ImmutablePair<List<ComponentInstance>, Map<String, String>>, StorageOperationStatus> cloneAllComponentInstancesFromContainerComponent(String componentIdFrom, String componentIdTo, NodeTypeEnum containerNodeType, + NodeTypeEnum compInstNodeType, LifecycleStateEnum targetLifecycle, TitanVertex metadataVertex, Resource prevResource, Resource newResource, Map<String, List<ComponentInstanceProperty>> inputsPropMap) { + + List<ComponentInstance> list = new ArrayList<ComponentInstance>(); + Map<String, String> oldCompInstToNew = new HashMap<>(); + + ImmutablePair<List<ComponentInstance>, Map<String, String>> result = new ImmutablePair<List<ComponentInstance>, Map<String, String>>(list, oldCompInstToNew); + + // Either<ImmutablePair<List<ComponentInstance>, + // List<RequirementCapabilityRelDef>>, StorageOperationStatus> + // allResourceInstances = getAllComponentInstances(componentIdFrom, + // containerNodeType, compInstNodeType, true); + // + // + // if (allResourceInstances.isRight()) { + // StorageOperationStatus status = allResourceInstances.right().value(); + // if (status.equals(StorageOperationStatus.NOT_FOUND)) { + // + // return Either.left(result); + // } else { + // log.error("failed to get all resource instances for service {}. + // status={}", componentIdFrom, status); + // return Either.right(status); + // } + // } + + // ImmutablePair<List<ComponentInstance>, + // List<RequirementCapabilityRelDef>> instanceRelationPair = + // allResourceInstances.left().value(); + + // ImmutablePair<List<ComponentInstance>, + // List<RequirementCapabilityRelDef>> instanceRelationPair = new + // ImmutablePair<List<ComponentInstance>, + // List<RequirementCapabilityRelDef>>(prevResource.getComponentInstances(), + // prevResource.getComponentInstancesRelations()); + List<ComponentInstance> riList = prevResource.getComponentInstances(); + Map<String, ComponentInstance> riMapper = new HashMap<>(); + int instanceNumber = 0; + long timeProperties = 0; + if (riList != null) { + for (ComponentInstance ri : riList) { + instanceNumber++; + String origRiUniqueID = ri.getUniqueId(); + Either<TitanVertex, StorageOperationStatus> createResourceInstance = createComponentInstance(componentIdTo, containerNodeType, String.valueOf(instanceNumber), false, ri, compInstNodeType, true, true, metadataVertex); + if (createResourceInstance.isRight()) { + StorageOperationStatus status = createResourceInstance.right().value(); + log.error("failed to clone resource instance {}. status ={}", origRiUniqueID, status); + return Either.right(status); + } + TitanVertex createdInstance = createResourceInstance.left().value(); + String createdInstanceId = (String) titanGenericDao.getProperty(createdInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + StorageOperationStatus associateArtifactsToResource = cloneResourceInstanceArtifacts(createdInstance, ri, targetLifecycle); + if (associateArtifactsToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} artifacts. error {} ", ri.getNormalizedName(), associateArtifactsToResource.name()); + return Either.right(associateArtifactsToResource); + } + + long start = System.currentTimeMillis(); + StorageOperationStatus associatePropertyValuesToResource = cloneResourceInstancePropertyValues(createdInstance, ri, inputsPropMap, newResource); + if (associatePropertyValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + long end = System.currentTimeMillis(); + timeProperties += (end - start); + + StorageOperationStatus associateAttributeValuesToResource = cloneResourceInstanceAttributeValues(createdInstance, ri, createdInstanceId); + if (associateAttributeValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} attribute values. error {} ", ri.getNormalizedName(), associateAttributeValuesToResource.name()); + return Either.right(associateAttributeValuesToResource); + } + + StorageOperationStatus associateInputValuesToResource = cloneResourceInstanceInputsValues(createdInstance, ri, createdInstanceId, newResource, null); + if (associateInputValuesToResource != StorageOperationStatus.OK) { + log.debug("failed to clone resource instance {} property values. error {} ", ri.getNormalizedName(), associatePropertyValuesToResource.name()); + return Either.right(associatePropertyValuesToResource); + } + Map<String, Object> properties = titanGenericDao.getProperties(createdInstance); + ComponentInstanceData createdComponentInstance = GraphElementFactory.createElement(NodeTypeEnum.ResourceInstance.getName(), GraphElementTypeEnum.Node, properties, ComponentInstanceData.class); + ComponentInstance createdResourceInstance = new ComponentInstance(createdComponentInstance.getComponentInstDataDefinition()); + riMapper.put(origRiUniqueID, createdResourceInstance); + + list.add(createdResourceInstance); + oldCompInstToNew.put(origRiUniqueID, createdResourceInstance.getUniqueId()); + } + } + log.info("*********** total properties in ms {}", timeProperties); + + // List<RequirementCapabilityRelDef> relationsList = + // instanceRelationPair.right; + List<RequirementCapabilityRelDef> relationsList = prevResource.getComponentInstancesRelations(); + if (relationsList != null) { + for (RequirementCapabilityRelDef relation : relationsList) { + String origFrom = relation.getFromNode(); + String origTo = relation.getToNode(); + relation.setFromNode(riMapper.get(origFrom).getUniqueId()); + relation.setToNode(riMapper.get(origTo).getUniqueId()); + List<RequirementAndRelationshipPair> relationships = relation.getRelationships(); + for (RequirementAndRelationshipPair pair : relationships) { + // for all atomic resource instances need to update to + // relevant + // new ri ids + String capOwnerId = pair.getCapabilityOwnerId(); + String reqOwnerId = pair.getRequirementOwnerId(); + if (isAtomicComponentInstance(riMapper.get(origFrom))) { + reqOwnerId = riMapper.get(reqOwnerId).getUniqueId(); + } + if (isAtomicComponentInstance(riMapper.get(origTo))) { + capOwnerId = riMapper.get(capOwnerId).getUniqueId(); + } + pair.setRequirementOwnerId(reqOwnerId); + pair.setCapabilityOwnerId(capOwnerId); + } + + Either<RequirementCapabilityRelDef, StorageOperationStatus> associateInstances = associateResourceInstances(componentIdTo, containerNodeType, relation, true); + if (associateInstances.isRight()) { + StorageOperationStatus status = associateInstances.right().value(); + log.error("failed to assosiate resource instance {} and resource instance {}. status ={}", relation.getFromNode(), relation.getToNode(), status); + return Either.right(status); + } + } + } + return Either.left(result); + } + + private boolean isAtomicComponentInstance(ComponentInstance componentInstance) { + OriginTypeEnum originType = componentInstance.getOriginType(); + if (originType.equals(OriginTypeEnum.VFC) || originType.equals(OriginTypeEnum.VL) || originType.equals(OriginTypeEnum.CP)) { + return true; + } + return false; + } + + private StorageOperationStatus cloneResourceInstanceArtifacts(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance, LifecycleStateEnum targetLifecycle) { + + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> getArtifactsOfRI = artifactOperation.getArtifacts(fromResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true); + if (getArtifactsOfRI.isRight()) { + StorageOperationStatus status = getArtifactsOfRI.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + status = StorageOperationStatus.OK; + } + return status; + } + + Map<String, ArtifactDefinition> artifacts = getArtifactsOfRI.left().value(); + for (Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + // US687135 Do not Add VF_MODULES_METADATA when checking out + if (ArtifactTypeEnum.VF_MODULES_METADATA.getType().equals(artifactDefinition.getArtifactType())) { + // The artifact of type VF_MODULES_METADATA should not be cloned + // unless we are changing the state to certified. + if (targetLifecycle != null && targetLifecycle != LifecycleStateEnum.CERTIFIED) { + continue; + } + } + Either<ArtifactDefinition, StorageOperationStatus> addArifactToResource = Either.left(artifactDefinition); + + addArifactToResource = artifactOperation.addArifactToComponent(artifactDefinition, toResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, false, true); + + if (addArifactToResource.isRight()) { + return addArifactToResource.right().value(); + } + } + toResourceInstance.setDeploymentArtifacts(artifacts); + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceArtifacts(TitanVertex toResourceInstance, ComponentInstance fromResourceInstance, LifecycleStateEnum targetLifecycle) { + + Either<Map<String, TitanVertex>, StorageOperationStatus> getArtifactsOfRI = artifactOperation.getArtifactsVertecies(fromResourceInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true); + if (getArtifactsOfRI.isRight()) { + StorageOperationStatus status = getArtifactsOfRI.right().value(); + if (status.equals(StorageOperationStatus.NOT_FOUND)) { + status = StorageOperationStatus.OK; + } + return status; + } + + Map<String, TitanVertex> artifacts = getArtifactsOfRI.left().value(); + for (Entry<String, TitanVertex> entry : artifacts.entrySet()) { + + TitanVertex artifactVertex = entry.getValue(); + // US687135 Do not Add VF_MODULES_METADATA when checking out + String artifactType = (String) titanGenericDao.getProperty(artifactVertex, GraphPropertiesDictionary.ARTIFACT_TYPE.getProperty()); + String label = (String) titanGenericDao.getProperty(artifactVertex, GraphPropertiesDictionary.ARTIFACT_LABEL.getProperty()); + if (ArtifactTypeEnum.VF_MODULES_METADATA.getType().equals(artifactType)) { + // The artifact of type VF_MODULES_METADATA should not be cloned + // unless we are changing the state to certified. + if (targetLifecycle != null && targetLifecycle != LifecycleStateEnum.CERTIFIED) { + continue; + } + } + + StorageOperationStatus addArifactToResource = artifactOperation.addArifactToComponent(artifactVertex, toResourceInstance, label); + + if (!addArifactToResource.equals(StorageOperationStatus.OK)) { + return addArifactToResource; + } + } + // toResourceInstance.setDeploymentArtifacts(artifacts); + return StorageOperationStatus.OK; + } + + public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, boolean inTransaction) { + + Either<Integer, StorageOperationStatus> result = null; + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource instance for id = {}", resourceInstanceId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + + VertexProperty<Object> vertexProperty = vertex.property(counterType.getProperty()); + Integer counter = 0; + if (vertexProperty.isPresent()) { + if (vertexProperty.value() != null) { + counter = (Integer) vertexProperty.value(); + } + } + + counter++; + vertex.property(counterType.getProperty(), counter); + + result = Either.left(counter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("increaseAndGetResourceInstanceSpecificCounter operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<Integer, StorageOperationStatus> increaseAndGetResourceInstanceSpecificCounter(TitanVertex resourceInstanceVertex, GraphPropertiesDictionary counterType) { + + Either<Integer, StorageOperationStatus> result = null; + + VertexProperty<Object> vertexProperty = resourceInstanceVertex.property(counterType.getProperty()); + Integer counter = 0; + if (vertexProperty.isPresent()) { + if (vertexProperty.value() != null) { + counter = (Integer) vertexProperty.value(); + } + } + counter++; + resourceInstanceVertex.property(counterType.getProperty(), counter); + + result = Either.left(counter); + return result; + + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllComponentInstancesNames(String serviceId, NodeTypeEnum nodeType, boolean inTransaction) { + + Either<List<String>, StorageOperationStatus> result = null; + + try { + + Either<List<String>, TitanOperationStatus> resInstancesOfService = getComponentInstancesNameOfService(serviceId, nodeType); + + log.debug("After fetching resource instances of service {}. Result is {}", serviceId, resInstancesOfService); + if (resInstancesOfService.isRight()) { + TitanOperationStatus status = resInstancesOfService.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find resource instances of service {}. Status is {}", serviceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<String> names = resInstancesOfService.left().value(); + + if (names == null || names.isEmpty()) { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + result = Either.left(names); + + } finally { + if (false == inTransaction) { + commitOrRollback(result); + } + } + return result; + } + + private Either<List<String>, TitanOperationStatus> getComponentInstancesNameOfService(String serviceId, NodeTypeEnum nodeType) { + + List<String> resourcesInstanseName = new ArrayList<String>(); + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(serviceId, nodeType, false); + if (resourceInstancesRes.isRight()) { + TitanOperationStatus status = resourceInstancesRes.right().value(); + log.debug("Resource instance was found under service {}. Status is {}", serviceId, status); + return Either.right(status); + } + + List<ImmutablePair<ComponentInstanceData, GraphEdge>> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + + for (ImmutablePair<ComponentInstanceData, GraphEdge> immutablePair : resourceInstances) { + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + resourcesInstanseName.add(resourceInstanceData.getComponentInstDataDefinition().getName()); + + } + } + + return Either.left(resourcesInstanseName); + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllComponentInstancesNames(String componentId, NodeTypeEnum nodeType) { + + return getAllComponentInstancesNames(componentId, nodeType, false); + } + + @Override + public Either<ComponentInstance, StorageOperationStatus> getResourceInstanceById(String resourceId) { + Either<ComponentInstanceData, TitanOperationStatus> resourceInstanceData = findResourceInstance(resourceId); + + if (resourceInstanceData.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceInstanceData.right().value())); + } + + return Either.left(new ComponentInstance(resourceInstanceData.left().value().getComponentInstDataDefinition())); + + } + + private StorageOperationStatus setCompInstDeploymentArtifactsFromGraph(Map<String, Map<String, ArtifactDefinition>> resourcesArtifacts, String uniqueId, ComponentInstance resourceInstance) { + + if (resourcesArtifacts.containsKey(uniqueId)) { + resourceInstance.setDeploymentArtifacts(resourcesArtifacts.get(uniqueId)); + return StorageOperationStatus.OK; + } + + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = artifactOperation.getArtifacts(uniqueId, NodeTypeEnum.Resource, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + return status; + } else { + return StorageOperationStatus.OK; + } + } + Map<String, ArtifactDefinition> artifacts = result.left().value(); + if (!artifacts.isEmpty()) { + Map<String, ArtifactDefinition> tempArtifacts = new HashMap<String, ArtifactDefinition>(artifacts); + for (Entry<String, ArtifactDefinition> artifact : artifacts.entrySet()) { + if (!artifact.getValue().checkEsIdExist()) { + tempArtifacts.remove(artifact.getKey()); + } + } + resourceInstance.setDeploymentArtifacts(tempArtifacts); + resourcesArtifacts.put(uniqueId, tempArtifacts); + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus setCompInstCapabilitiesFromGraph(Map<String, Map<String, CapabilityDefinition>> resourcesCapabilities, Component component, NodeTypeEnum compInstType, ComponentInstance resourceInstance, + List<String> respourceDerivedList) { + + StorageOperationStatus status; + ComponentOperation componentOperation = getComponentOperation(compInstType); + Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherCapabilities = componentOperation.getCapabilities(component, compInstType, true); + if (eitherCapabilities.isLeft()) { + status = StorageOperationStatus.OK; + Map<String, List<CapabilityDefinition>> capabilities = eitherCapabilities.left().value(); + if (capabilities != null && !capabilities.isEmpty()) { + capabilities.forEach((type, list) -> { + if (list != null && !list.isEmpty()) { + list.forEach((capability) -> { + // We want to set ownerId only for instances coming + // from atomic resources, otherwise we don't want + // to overwrite the existing ownerId of underlying + // component instances + if (isAtomicResource(component)) { + capability.setOwnerId(resourceInstance.getUniqueId()); + capability.setOwnerName(resourceInstance.getName()); + capability.setCapabilitySources(respourceDerivedList); + } + }); + } + }); + resourceInstance.setCapabilities(capabilities); + } + } else { + status = StorageOperationStatus.GENERAL_ERROR; + } + return status; + + } + + private StorageOperationStatus setCompInstRequirementsFromGraph(Map<String, Map<String, RequirementDefinition>> resourcesReq, Component component, NodeTypeEnum compInstType, ComponentInstance resourceInstance) { + StorageOperationStatus status; + ComponentOperation componentOperation = getComponentOperation(compInstType); + Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherCapabilities = componentOperation.getRequirements(component, compInstType, true); + if (eitherCapabilities.isLeft()) { + status = StorageOperationStatus.OK; + Map<String, List<RequirementDefinition>> requirements = eitherCapabilities.left().value(); + if (requirements != null && !requirements.isEmpty()) { + // We want to set ownerId only for instances coming from atomic + // resources, otherwise we don't want + // to overwrite the existing ownerId of underlying component + // instances + if (isAtomicResource(component)) { + requirements.forEach((type, list) -> { + if (list != null && !list.isEmpty()) { + list.forEach((requirement) -> { + requirement.setOwnerId(resourceInstance.getUniqueId()); + requirement.setOwnerName(resourceInstance.getName()); + }); + } + }); + } + resourceInstance.setRequirements(requirements); + } + } else { + status = StorageOperationStatus.GENERAL_ERROR; + } + return status; + } + + public Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> getCapabilities(ComponentInstance compInstance, NodeTypeEnum nodeTypeEnum) { + + DataNodeCollector<CapabilityData> collector = () -> titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), compInstance.getUniqueId(), GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, + CapabilityData.class); + + return getDataFromGraph(collector); + + } + + public Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus> getRequirements(ComponentInstance compInstance, NodeTypeEnum nodeTypeEnum) { + + DataNodeCollector<RequirementData> collector = () -> titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeTypeEnum), compInstance.getUniqueId(), GraphEdgeLabels.CALCULATED_REQUIREMENT, NodeTypeEnum.Requirement, + RequirementData.class); + + return getDataFromGraph(collector); + + } + + public Either<Boolean, StorageOperationStatus> isAvailableRequirement(ComponentInstance fromResInstance, RequirementAndRelationshipPair relationPair) { + Either<TitanVertex, TitanOperationStatus> fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), fromResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {} error {}", fromResInstance.getUniqueId(), fromRi.right().value()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Iterator<Edge> edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_REQUIREMENT.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_REQUIREMENT edges. All full filled for RI {}", fromResInstance.getUniqueId()); + return Either.left(false); + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String reqId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement)); + if (reqId.equals(relationPair.getRequirementUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getRequirementOwnerId())) { + String leftOccurrences = (String) edge.value(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(RequirementData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return Either.left(exist); + } + + public Either<Boolean, StorageOperationStatus> isAvailableCapabilty(ComponentInstance toResInstance, RequirementAndRelationshipPair relationPair) { + Either<TitanVertex, TitanOperationStatus> fromRi = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), toResInstance.getUniqueId()); + if (fromRi.isRight()) { + log.debug("Failed to fetch component instance {}. Error: {}", toResInstance.getUniqueId(), fromRi.right().value()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Iterator<Edge> edgeIter = fromRi.left().value().edges(Direction.OUT, GraphEdgeLabels.CALCULATED_CAPABILITY.name()); + if (edgeIter == null || !edgeIter.hasNext()) { + log.debug("No available CALCULATED_CAPABILITY edges. All full filled for RI {}", toResInstance.getUniqueId()); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + boolean exist = false; + while (edgeIter.hasNext()) { + Edge edge = edgeIter.next(); + TitanVertex reqVertex = (TitanVertex) edge.inVertex(); + String capId = (String) titanGenericDao.getProperty(reqVertex, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability)); + if (capId.equals(relationPair.getCapabilityUid())) { + String ownerIdOnEdge = (String) edge.value(GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + if (ownerIdOnEdge.equals(relationPair.getCapabilityOwnerId())) { + String leftOccurrences = (String) edge.value(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null && !leftOccurrences.equals(CapabilityData.MAX_OCCURRENCES)) { + Integer leftIntValue = Integer.parseInt(leftOccurrences); + if (leftIntValue > 0) { + exist = true; + } + } else { + exist = true; + } + break; + } + } + } + return Either.left(exist); + } + + interface DataNodeCollector<Data> { + Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus> getDataNodes(); + } + + public <Data> Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus> getDataFromGraph(DataNodeCollector<Data> dataCollector) { + Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus> eitherRet; + + Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus> childrenNodes = dataCollector.getDataNodes(); + + if (childrenNodes.isLeft()) { + List<ImmutablePair<Data, GraphEdge>> collectedData = childrenNodes.left().value().stream().map(element -> new ImmutablePair<Data, GraphEdge>(element.getLeft(), element.getRight())).collect(Collectors.toList()); + eitherRet = Either.left(collectedData); + } else { + eitherRet = Either.right(childrenNodes.right().value()); + } + return eitherRet; + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + if (NodeTypeEnum.Service == componentType) { + return serviceOperation; + } else if (NodeTypeEnum.Resource == componentType) { + return resourceOperation; + } + return null; + } + + private boolean isAtomicResource(Component component) { + // true if component is of type VL/CP/VFC + boolean isFromAtomicResource = (component.getComponentType() == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() != ResourceTypeEnum.VF); + return isFromAtomicResource; + } + + private StorageOperationStatus cloneResourceInstanceAttributeValues(ComponentInstance createdInstance, ComponentInstance resourceInstance) { + Wrapper<StorageOperationStatus> storageStatusWrapper = new Wrapper<>(); + Wrapper<List<ComponentInstanceAttribute>> compInstanceAttList = new Wrapper<>(); + + findAllAttributesOfResourceInstance(resourceInstance, compInstanceAttList, storageStatusWrapper); + + if (storageStatusWrapper.isEmpty()) { + validateListNotEmpty(storageStatusWrapper, compInstanceAttList.getInnerElement()); + } + + if (storageStatusWrapper.isEmpty()) { + List<ComponentInstanceAttribute> attributesOnInstance = compInstanceAttList.getInnerElement(); + for (int i = 0; i < attributesOnInstance.size() && storageStatusWrapper.isEmpty(); i++) { + cloneSingleAttributeOnResourceInstance(createdInstance, attributesOnInstance.get(i), storageStatusWrapper); + } + } + + StorageOperationStatus result = storageStatusWrapper.isEmpty() ? StorageOperationStatus.OK : storageStatusWrapper.getInnerElement(); + return result; + + } + + private StorageOperationStatus cloneResourceInstanceAttributeValues(TitanVertex createdInstanceVertex, ComponentInstance resourceInstance, String instanceId) { + Wrapper<StorageOperationStatus> storageStatusWrapper = new Wrapper<>(); + Wrapper<List<ComponentInstanceAttribute>> compInstanceAttList = new Wrapper<>(); + + findAllAttributesOfResourceInstance(resourceInstance, compInstanceAttList, storageStatusWrapper); + + if (storageStatusWrapper.isEmpty()) { + validateListNotEmpty(storageStatusWrapper, compInstanceAttList.getInnerElement()); + } + + if (storageStatusWrapper.isEmpty()) { + List<ComponentInstanceAttribute> attributesOnInstance = compInstanceAttList.getInnerElement(); + for (int i = 0; i < attributesOnInstance.size() && storageStatusWrapper.isEmpty(); i++) { + StorageOperationStatus result = cloneSingleAttributeOnResourceInstance(createdInstanceVertex, attributesOnInstance.get(i), instanceId); + if (!result.equals(StorageOperationStatus.OK)) { + log.trace("Failed to clone attribute for instance {} error {}", instanceId, result); + return result; + } + } + } + + StorageOperationStatus result = storageStatusWrapper.isEmpty() ? StorageOperationStatus.OK : storageStatusWrapper.getInnerElement(); + return result; + + } + + private <T> void validateListNotEmpty(Wrapper<StorageOperationStatus> storageStatusWrapper, List<T> attributesOnInstance) { + if (attributesOnInstance == null || attributesOnInstance.isEmpty() == true) { + storageStatusWrapper.setInnerElement(StorageOperationStatus.OK); + } + } + + private void findAllAttributesOfResourceInstance(ComponentInstance resourceInstance, Wrapper<List<ComponentInstanceAttribute>> compInstanceAttList, Wrapper<StorageOperationStatus> storageStatusWrapper) { + + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> allAttributes = attributeOperation.getAllAttributesOfResourceInstance(resourceInstance); + if (allAttributes.isRight()) { + TitanOperationStatus status = allAttributes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + storageStatusWrapper.setInnerElement(storageStatus); + } else { + compInstanceAttList.setInnerElement(allAttributes.left().value()); + } + } + + private void cloneSingleAttributeOnResourceInstance(ComponentInstance createdInstance, ComponentInstanceAttribute attribute, Wrapper<StorageOperationStatus> storageStatusWrapper) { + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (attribute.getValueUniqueUid() != null) { + attribute.setValueUniqueUid(null); + Either<Integer, StorageOperationStatus> counterRes = increaseAndGetResourceInstanceSpecificCounter(createdInstance.getUniqueId(), GraphPropertiesDictionary.ATTRIBUTE_COUNTER, true); + if (counterRes.isRight()) { + storageStatusWrapper.setInnerElement(counterRes.right().value()); + } else { + Either<AttributeValueData, TitanOperationStatus> addAttributeToResourceInstance = addAttributeToResourceInstance(attribute, createdInstance.getUniqueId(), counterRes.left().value()); + + if (addAttributeToResourceInstance.isRight()) { + TitanOperationStatus status = addAttributeToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + storageStatusWrapper.setInnerElement(storageStatus); + } + } + } + + } + + private StorageOperationStatus cloneSingleAttributeOnResourceInstance(TitanVertex createdInstanceVertex, ComponentInstanceAttribute attribute, String instanceId) { + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (attribute.getValueUniqueUid() != null) { + attribute.setValueUniqueUid(null); + Either<Integer, StorageOperationStatus> counterRes = increaseAndGetResourceInstanceSpecificCounter(createdInstanceVertex, GraphPropertiesDictionary.ATTRIBUTE_COUNTER); + if (counterRes.isRight()) { + return counterRes.right().value(); + } else { + Either<AttributeValueData, TitanOperationStatus> addAttributeToResourceInstance = addAttributeToResourceInstance(attribute, instanceId, counterRes.left().value()); + + if (addAttributeToResourceInstance.isRight()) { + TitanOperationStatus status = addAttributeToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + } + return StorageOperationStatus.OK; + + } + + private void connectAttValueDataToComponentInstanceData(Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData compIns, AttributeValueData attValueData) { + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.ATTRIBUTE_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToComponentInstanceData", + "Failed to associate resource instance " + compIns.getUniqueId() + " attribute value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + } + } + + private void connectInputValueDataToComponentInstanceData(Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData compIns, InputValueData attValueData) { + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(compIns, attValueData, GraphEdgeLabels.INPUT_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("connectInputValueDataToComponentInstanceData", + "Failed to associate resource instance " + compIns.getUniqueId() + " input value " + attValueData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + } + } + + private void connectAttValueDataToAttData(Wrapper<TitanOperationStatus> errorWrapper, AttributeData attData, AttributeValueData attValueData) { + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.ATTRIBUTE_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("connectAttValueDataToAttData", + "Failed to associate attribute value " + attValueData.getUniqueId() + " to attribute " + attData.getUniqueId() + " in graph. status is " + operationStatus, ErrorSeverity.ERROR); + + errorWrapper.setInnerElement(operationStatus); + } + } + + private void connectInputValueDataToInputData(Wrapper<TitanOperationStatus> errorWrapper, InputsData attData, InputValueData attValueData) { + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(attValueData, attData, GraphEdgeLabels.INPUT_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("connectInputValueDataToInputData", "Failed to associate input value " + attValueData.getUniqueId() + " to input " + attData.getUniqueId() + " in graph. status is " + operationStatus, + ErrorSeverity.ERROR); + + errorWrapper.setInnerElement(operationStatus); + } + } + + private void createAttributeValueDataNode(ComponentInstanceAttribute attributeInstanceProperty, Integer index, Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData resourceInstanceData, + Wrapper<AttributeValueData> attValueDataWrapper) { + String valueUniqueUid = attributeInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceAttributeValueUid(resourceInstanceData.getUniqueId(), index); + AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute(attributeInstanceProperty, attValueDatauniqueId); + + log.debug("Before adding attribute value to graph {}", attributeValueData); + Either<AttributeValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class); + log.debug("After adding attribute value to graph {}", attributeValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + errorWrapper.setInnerElement(operationStatus); + } else { + attValueDataWrapper.setInnerElement(createNodeResult.left().value()); + } + + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR); + errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); + } + } + + /* + * private void createInputValueDataNode(ComponentInstanceInput inputInstanceProperty, Integer index, Wrapper<TitanOperationStatus> errorWrapper, ComponentInstanceData resourceInstanceData, Wrapper<AttributeValueData> attValueDataWrapper) { + * String valueUniqueUid = inputInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { + * + * String attValueDatauniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData. getUniqueId(), index); AttributeValueData attributeValueData = buildAttributeValueDataFromComponentInstanceAttribute( inputInstanceProperty, + * attValueDatauniqueId); + * + * log.debug("Before adding attribute value to graph {}", attributeValueData); Either<AttributeValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(attributeValueData, AttributeValueData.class); + * log.debug("After adding attribute value to graph {}", attributeValueData); + * + * if (createNodeResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right().value(); errorWrapper.setInnerElement(operationStatus); } else { attValueDataWrapper.setInnerElement(createNodeResult.left().value()); } + * + * } else { BeEcompErrorManager.getInstance().logInternalFlowError( "CreateAttributeValueDataNode", "attribute value already exists.", ErrorSeverity.ERROR); errorWrapper.setInnerElement(TitanOperationStatus.ALREADY_EXIST); } } + */ + + private AttributeValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceAttribute resourceInstanceAttribute, String uniqueId) { + AttributeValueData attributeValueData = new AttributeValueData(); + attributeValueData.setUniqueId(uniqueId); + attributeValueData.setHidden(resourceInstanceAttribute.isHidden()); + attributeValueData.setValue(resourceInstanceAttribute.getValue()); + attributeValueData.setType(resourceInstanceAttribute.getType()); + long currentTimeMillis = System.currentTimeMillis(); + attributeValueData.setCreationTime(currentTimeMillis); + attributeValueData.setModificationTime(currentTimeMillis); + return attributeValueData; + } + + private InputValueData buildAttributeValueDataFromComponentInstanceAttribute(ComponentInstanceInput resourceInstanceInput, String uniqueId) { + InputValueData inputValueData = new InputValueData(); + inputValueData.setUniqueId(uniqueId); + inputValueData.setHidden(resourceInstanceInput.isHidden()); + inputValueData.setValue(resourceInstanceInput.getValue()); + inputValueData.setType(resourceInstanceInput.getType()); + long currentTimeMillis = System.currentTimeMillis(); + inputValueData.setCreationTime(currentTimeMillis); + inputValueData.setModificationTime(currentTimeMillis); + return inputValueData; + } + + private StorageOperationStatus cloneResourceInstancePropertyValues(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance) { + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> allProperties = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List<ComponentInstanceProperty> propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceProperty property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List<PropertyRule> rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(toResourceInstance.getUniqueId()); + } + } + + } else { + continue; + } + + String resourceInstanceId = toResourceInstance.getUniqueId(); + + Either<Integer, StorageOperationStatus> counterRes = this.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.PROPERTY_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance = this.addPropertyToResourceInstance(property, toResourceInstance.getUniqueId(), false, index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstancePropertyValues(TitanVertex toResourceInstance, ComponentInstance fromResourceInstance, Map<String, List<ComponentInstanceProperty>> inputsPropMap, Resource newResource) { + + String riId = (String) titanGenericDao.getProperty(toResourceInstance, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + Either<List<ComponentInstanceProperty>, TitanOperationStatus> allProperties = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(fromResourceInstance.getUniqueId()); + List<InputDefinition> newInputs = newResource.getInputs(); + // + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List<ComponentInstanceProperty> propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceProperty property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List<PropertyRule> rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(riId); + } + } + + } else { + continue; + } + + String resourceInstanceId = riId; + + Either<Integer, StorageOperationStatus> counterRes = this.increaseAndGetResourceInstanceSpecificCounter(toResourceInstance, GraphPropertiesDictionary.PROPERTY_COUNTER); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either<ComponentInstanceProperty, TitanOperationStatus> addPropertyToResourceInstance = this.addPropertyToResourceInstance(property, toResourceInstance, false, index, resourceInstanceId); + + if (addPropertyToResourceInstance.isRight() && !addPropertyToResourceInstance.right().value().equals(TitanOperationStatus.OK)) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToResourceInstance.right().value()); + return storageStatus; + } + if (addPropertyToResourceInstance.isLeft()) { + ComponentInstanceProperty newProp = addPropertyToResourceInstance.left().value(); + Set<String> inputsKey = inputsPropMap.keySet(); + String inputToAssName = null; + GetInputValueInfo getInputInfo = null; + for (String inputName : inputsKey) { + List<ComponentInstanceProperty> propsList = inputsPropMap.get(inputName); + Optional<ComponentInstanceProperty> op = propsList.stream().filter(p -> p.getUniqueId().equals(property.getUniqueId())).findAny(); + if (op.isPresent()) { + ComponentInstanceProperty inpProp = op.get(); + getInputInfo = new GetInputValueInfo(); + getInputInfo.setPropName(inpProp.getName()); + getInputInfo.setInputName(inputName); + inputToAssName = inputName; + break; + } + + } + if (inputToAssName != null) { + for (InputDefinition input1 : newInputs) { + if (input1.getName().equals(inputToAssName)) { + this.inputOperation.associatePropertyToInput(riId, input1.getUniqueId(), newProp, getInputInfo); + break; + } + } + } + + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceInputsValues(ComponentInstance toResourceInstance, ComponentInstance fromResourceInstance, Component comonentTo, Map<String, List<ComponentInstanceInput>> inputsValuesMap) { + + Either<List<ComponentInstanceInput>, TitanOperationStatus> allProperties = inputOperation.getAllInputsOfResourceInstanceOnlyInputDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List<ComponentInstanceInput> propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + List<InputDefinition> newInputs = comonentTo.getInputs(); + + for (ComponentInstanceInput property : propertiesOnInstance) { + + List<InputDefinition> inputToAss = new ArrayList<InputDefinition>(); + if (newInputs != null && !inputsValuesMap.isEmpty()) { + + Set<String> inputsName = inputsValuesMap.keySet(); + for (String name : inputsName) { + List<ComponentInstanceInput> inputsValue = inputsValuesMap.get(name); + if (inputsValue != null) { + Optional<ComponentInstanceInput> op = inputsValue.stream().filter(p -> p.getValueUniqueUid().equals(property.getValueUniqueUid())).findAny(); + if (op.isPresent()) { + Optional<InputDefinition> optional = newInputs.stream().filter(e -> e.getName().equals(name)).findAny(); + if (optional.isPresent()) { + inputToAss.add(optional.get()); + } + } + } + } + } + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List<PropertyRule> rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(toResourceInstance.getUniqueId()); + } + } + + } else { + continue; + } + + String resourceInstanceId = toResourceInstance.getUniqueId(); + + Either<Integer, StorageOperationStatus> counterRes = this.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.INPUT_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either<InputValueData, TitanOperationStatus> addPropertyToResourceInstance = this.addInputToResourceInstance(property, toResourceInstance.getUniqueId(), index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + for (InputDefinition input : inputToAss) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), input.getName()); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), toResourceInstance.getUniqueId()); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, input.getUniqueId()); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, addPropertyToResourceInstance.left().value().getUniqueId()); + + Either<GraphRelation, TitanOperationStatus> addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + TitanOperationStatus status = addPropRefResult.right().value(); + log.debug("Failed to associate input {} to input value {} in graph. Status is {}", input.getUniqueId(), propertyData.getUniqueId(), status); + + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + } + } + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus cloneResourceInstanceInputsValues(TitanVertex toResourceInstanceVertex, ComponentInstance fromResourceInstance, String instanceId, Resource newResource, Map<String, List<ComponentInstanceInput>> inputsValuesMap) { + + Either<List<ComponentInstanceInput>, TitanOperationStatus> allProperties = inputOperation.getAllInputsOfResourceInstanceOnlyInputDefId(fromResourceInstance.getUniqueId()); + if (allProperties.isRight()) { + TitanOperationStatus status = allProperties.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + + List<ComponentInstanceInput> propertiesOnInstance = allProperties.left().value(); + if (propertiesOnInstance == null || propertiesOnInstance.isEmpty() == true) { + return StorageOperationStatus.OK; + } + + for (ComponentInstanceInput property : propertiesOnInstance) { + + // Only if valueUniqueId is not empty, then its belongs to the + // instance + if (property.getValueUniqueUid() != null) { + property.setValueUniqueUid(null); + List<PropertyRule> rules = property.getRules(); + if (rules != null) { + for (PropertyRule propertyRule : rules) { + propertyRule.replaceFirstToken(instanceId); + } + } + + } else { + continue; + } + + String resourceInstanceId = instanceId; + + Either<Integer, StorageOperationStatus> counterRes = this.increaseAndGetResourceInstanceSpecificCounter(toResourceInstanceVertex, GraphPropertiesDictionary.INPUT_COUNTER); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + return status; + } + Integer index = counterRes.left().value(); + + Either<InputValueData, TitanOperationStatus> addPropertyToResourceInstance = this.addInputToResourceInstance(property, resourceInstanceId, index); + + if (addPropertyToResourceInstance.isRight()) { + TitanOperationStatus status = addPropertyToResourceInstance.right().value(); + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return storageStatus; + } + } + + return StorageOperationStatus.OK; + } + + public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) { + + Either<ComponentInstanceProperty, StorageOperationStatus> result = null; + + try { + // TODO: verify validUniqueId exists + Either<PropertyValueData, TitanOperationStatus> eitherStatus = this.updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, true); + + if (eitherStatus.isRight()) { + log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceProperty.getPath(), propertyValueData.getUniqueId(), resourceInstanceProperty.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private static final class UpdateDataContainer<SomeData, SomeValueData> { + final Wrapper<SomeValueData> valueDataWrapper; + final Wrapper<SomeData> dataWrapper; + final GraphEdgeLabels graphEdge; + final Supplier<Class<SomeData>> someDataClassGen; + final Supplier<Class<SomeValueData>> someValueDataClassGen; + final NodeTypeEnum nodeType; + final NodeTypeEnum nodeTypeValue; + + private UpdateDataContainer(GraphEdgeLabels graphEdge, Supplier<Class<SomeData>> someDataClassGen, Supplier<Class<SomeValueData>> someValueDataClassGen, NodeTypeEnum nodeType, NodeTypeEnum nodeTypeValue) { + super(); + this.valueDataWrapper = new Wrapper<>(); + this.dataWrapper = new Wrapper<>(); + this.graphEdge = graphEdge; + this.someDataClassGen = someDataClassGen; + this.someValueDataClassGen = someValueDataClassGen; + this.nodeType = nodeType; + this.nodeTypeValue = nodeTypeValue; + } + + public Wrapper<SomeValueData> getValueDataWrapper() { + return valueDataWrapper; + } + + public Wrapper<SomeData> getDataWrapper() { + return dataWrapper; + } + + public GraphEdgeLabels getGraphEdge() { + return graphEdge; + } + + public Supplier<Class<SomeData>> getSomeDataClassGen() { + return someDataClassGen; + } + + public Supplier<Class<SomeValueData>> getSomeValueDataClassGen() { + return someValueDataClassGen; + } + + public NodeTypeEnum getNodeType() { + return nodeType; + } + + public NodeTypeEnum getNodeTypeValue() { + return nodeTypeValue; + } + } + + @Override + public Either<AttributeValueData, TitanOperationStatus> createOrUpdateAttributeOfResourceInstance(ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId) { + Either<AttributeValueData, TitanOperationStatus> result; + // Create + if (attributeInstanceProperty.getValueUniqueUid() == null) { + Either<Integer, StorageOperationStatus> counterRes = increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.ATTRIBUTE_COUNTER, true); + if (counterRes.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("createOrUpdateAttributeOfResourceInstance", "Failed to get AttributeValueData Counter", ErrorSeverity.ERROR); + result = Either.right(TitanOperationStatus.GENERAL_ERROR); + + } else { + result = addAttributeToResourceInstance(attributeInstanceProperty, resourceInstanceId, counterRes.left().value()); + } + } + // Update + else { + result = updateAttributeOfResourceInstance(attributeInstanceProperty, resourceInstanceId); + } + return result; + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceAttribute + * @param resourceInstanceId + * @return + */ + private Either<AttributeValueData, TitanOperationStatus> updateAttributeOfResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId) { + + Either<AttributeValueData, TitanOperationStatus> result = null; + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + UpdateDataContainer<AttributeData, AttributeValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.ATTRIBUTE_IMPL, (() -> AttributeData.class), (() -> AttributeValueData.class), NodeTypeEnum.Attribute, + NodeTypeEnum.AttributeValue); + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceAttribute, resourceInstanceId, errorWrapper); + if (errorWrapper.isEmpty()) { + AttributeValueData attributeValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); + attributeValueData.setHidden(resourceInstanceAttribute.isHidden()); + attributeValueData.setValue(resourceInstanceAttribute.getValue()); + Either<AttributeValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(attributeValueData, AttributeValueData.class); + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + errorWrapper.setInnerElement(status); + } else { + result = Either.left(updateRes.left().value()); + } + } + if (!errorWrapper.isEmpty()) { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + + } + + private Either<AttributeValueData, TitanOperationStatus> addAttributeToResourceInstance(ComponentInstanceAttribute attributeInstanceProperty, String resourceInstanceId, Integer index) { + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + Wrapper<ComponentInstanceData> compInsWrapper = new Wrapper<>(); + Wrapper<AttributeData> attDataWrapper = new Wrapper<>(); + Wrapper<AttributeValueData> attValueDataWrapper = new Wrapper<>(); + + // Verify RI Exist + validateRIExist(resourceInstanceId, compInsWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + // Verify Attribute Exist + validateElementExistInGraph(attributeInstanceProperty.getUniqueId(), NodeTypeEnum.Attribute, () -> AttributeData.class, attDataWrapper, errorWrapper); + } + if (errorWrapper.isEmpty()) { + // Create AttributeValueData that is connected to RI + createAttributeValueDataNode(attributeInstanceProperty, index, errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper); + } + if (errorWrapper.isEmpty()) { + // Connect AttributeValueData (Att on RI) to AttData (Att on + // Resource) + connectAttValueDataToAttData(errorWrapper, attDataWrapper.getInnerElement(), attValueDataWrapper.getInnerElement()); + } + if (errorWrapper.isEmpty()) { + // Connect AttributeValueData to RI + connectAttValueDataToComponentInstanceData(errorWrapper, compInsWrapper.getInnerElement(), attValueDataWrapper.getInnerElement()); + } + + if (errorWrapper.isEmpty()) { + return Either.left(attValueDataWrapper.getInnerElement()); + } else { + return Either.right(errorWrapper.getInnerElement()); + } + + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceProerty + * @param resourceInstanceId + * @return + */ + public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance(ComponentInstanceProperty resourceInstanceProerty, String resourceInstanceId, boolean isValidate) { + + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + UpdateDataContainer<PropertyData, PropertyValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.PROPERTY_IMPL, (() -> PropertyData.class), (() -> PropertyValueData.class), NodeTypeEnum.Property, + NodeTypeEnum.PropertyValue); + + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceProerty, resourceInstanceId, errorWrapper); + if (!errorWrapper.isEmpty()) { + return Either.right(errorWrapper.getInnerElement()); + } + + else { + String value = resourceInstanceProerty.getValue(); + // Specific Validation Logic + PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + // Specific Update Logic + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + PropertyValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); + log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); + propertyValueData.setValue(newValue); + + ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProerty.getRules(), innerType, allDataTypes.left().value(), isValidate); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProerty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.updateRulesInPropertyValue(propertyValueData, resourceInstanceProerty, resourceInstanceId); + + Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); + if (updateRes.isRight()) { + TitanOperationStatus status = updateRes.right().value(); + return Either.right(status); + } else { + return Either.left(updateRes.left().value()); + } + } + + } + + /** + * update value of attribute on resource instance + * + * @param resourceInstanceProerty + * @param resourceInstanceId + * @return + */ + public Either<InputValueData, TitanOperationStatus> updateInputOfResourceInstance(ComponentInstanceInput resourceInstanceProerty, String resourceInstanceId) { + + Wrapper<TitanOperationStatus> errorWrapper = new Wrapper<>(); + UpdateDataContainer<PropertyData, InputValueData> updateDataContainer = new UpdateDataContainer<>(GraphEdgeLabels.INPUT_IMPL, (() -> PropertyData.class), (() -> InputValueData.class), NodeTypeEnum.Input, NodeTypeEnum.InputValue); + + preUpdateElementOfResourceInstanceValidations(updateDataContainer, resourceInstanceProerty, resourceInstanceId, errorWrapper); + if (!errorWrapper.isEmpty()) { + return Either.right(errorWrapper.getInnerElement()); + } + + else { + String value = resourceInstanceProerty.getValue(); + // Specific Validation Logic + PropertyData propertyData = updateDataContainer.getDataWrapper().getInnerElement(); + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + // Specific Update Logic + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + /* + * Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value()); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != + * null) { newValue = object.toString(); } } InputValueData propertyValueData = updateDataContainer.getValueDataWrapper().getInnerElement(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); propertyValueData.setValue(newValue); + * + * ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProerty.getRules(), innerType, allDataTypes.left().value()); if (pair.getRight() != null && pair.getRight() == false) { + * BeEcompErrorManager.getInstance(). logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProerty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } + * propertyOperation.updateRulesInPropertyValue(propertyValueData, resourceInstanceProerty, resourceInstanceId); + * + * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return + * Either.right(status); } else { return Either.left(updateRes.left().value()); } + */ + } + return null; + + } + + private <SomeData extends GraphNode, SomeValueData extends GraphNode> void preUpdateElementOfResourceInstanceValidations(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty, + String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) { + + if (errorWrapper.isEmpty()) { + // Verify VFC instance Exist + validateRIExist(resourceInstanceId, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify Property connected to VFC exist + validateElementConnectedToComponentExist(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify PropertyValue connected to VFC Instance exist + validateElementConnectedToComponentInstanceExist(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Example: Verify PropertyValue connected Property + validateElementConnectedToInstance(updateDataContainer, resourceInstanceProerty, errorWrapper); + } + } + + private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToInstance(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, IComponentInstanceConnectedElement resourceInstanceProerty, + Wrapper<TitanOperationStatus> errorWrapper) { + Either<ImmutablePair<SomeData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), resourceInstanceProerty.getValueUniqueUid(), + updateDataContainer.getGraphEdge(), updateDataContainer.getNodeType(), updateDataContainer.getSomeDataClassGen().get()); + + if (child.isRight()) { + TitanOperationStatus status = child.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + + } else { + updateDataContainer.getDataWrapper().setInnerElement(child.left().value().left); + } + } + + private <SomeValueData extends GraphNode, SomeData extends GraphNode> void validateElementConnectedToComponentInstanceExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, + IComponentInstanceConnectedElement resourceInstanceProerty, Wrapper<TitanOperationStatus> errorWrapper) { + String valueUniqueUid = resourceInstanceProerty.getValueUniqueUid(); + if (valueUniqueUid == null) { + errorWrapper.setInnerElement(TitanOperationStatus.INVALID_ID); + } else { + Either<SomeValueData, TitanOperationStatus> findPropertyValueRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeTypeValue()), valueUniqueUid, updateDataContainer.getSomeValueDataClassGen().get()); + if (findPropertyValueRes.isRight()) { + TitanOperationStatus status = findPropertyValueRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + } else { + updateDataContainer.getValueDataWrapper().setInnerElement(findPropertyValueRes.left().value()); + } + } + } + + private <SomeData extends GraphNode, SomeValueData extends GraphNode> void validateElementConnectedToComponentExist(UpdateDataContainer<SomeData, SomeValueData> updateDataContainer, + IComponentInstanceConnectedElement resourceInstanceElementConnected, Wrapper<TitanOperationStatus> errorWrapper) { + String uniqueId = resourceInstanceElementConnected.getUniqueId(); + Either<SomeData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(updateDataContainer.getNodeType()), uniqueId, updateDataContainer.getSomeDataClassGen().get()); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + errorWrapper.setInnerElement(status); + } + } + + private void validateRIExist(String resourceInstanceId, Wrapper<TitanOperationStatus> errorWrapper) { + validateRIExist(resourceInstanceId, null, errorWrapper); + } + + private void validateRIExist(String resourceInstanceId, Wrapper<ComponentInstanceData> compInsDataWrapper, Wrapper<TitanOperationStatus> errorWrapper) { + validateElementExistInGraph(resourceInstanceId, NodeTypeEnum.ResourceInstance, () -> ComponentInstanceData.class, compInsDataWrapper, errorWrapper); + } + + public <ElementData extends GraphNode> void validateElementExistInGraph(String elementUniqueId, NodeTypeEnum elementNodeType, Supplier<Class<ElementData>> elementClassGen, Wrapper<ElementData> elementDataWrapper, + Wrapper<TitanOperationStatus> errorWrapper) { + Either<ElementData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(elementNodeType), elementUniqueId, elementClassGen.get()); + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + errorWrapper.setInnerElement(status); + } else { + if (elementDataWrapper != null) { + elementDataWrapper.setInnerElement(findResInstanceRes.left().value()); + } + } + } + + /** + * add property to resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @param index + * @return + */ + public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isValidate, Integer index) { + + Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String propertyId = resourceInstanceProperty.getUniqueId(); + Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + PropertyData propertyData = findPropertyDefRes.left().value(); + ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + + ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(resourceInstanceId, propertyId); + if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.debug("The property {} already added to the resource instance {}", propertyId, resourceInstanceId); + resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight()); + Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate); + if (updatePropertyOfResourceInstance.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + return Either.right(updatePropertyOfResourceInstance.right().value()); + } + return Either.left(updatePropertyOfResourceInstance.left().value()); + } + + if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.debug("After finding property value of {} on component instance {}", propertyId, resourceInstanceId); + return Either.right(isPropertyValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceProperty.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceData.getUniqueId(), index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.debug("Before validateAndUpdateRules"); + ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules(), innerType, allDataTypes.left().value(), isValidate); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.addRulesToNewPropertyValue(propertyValueData, resourceInstanceProperty, resourceInstanceId); + + log.debug("Before adding property value to graph {}", propertyValueData); + Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + propertyValueData = createNodeResult.left().value(); + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + return Either.left(propertyValueData); + } else { + log.error("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + public Either<ComponentInstanceProperty, TitanOperationStatus> addPropertyToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, TitanVertex resourceInstanceVertex, boolean isValidate, Integer index, String resourceInstanceId) { + + String propertyId = resourceInstanceProperty.getUniqueId(); + Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); + if (valueUniqueUid == null) { + + PropertyData propertyData = findPropertyDefRes.left().value(); + + ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = propertyOperation.findPropertyValue(resourceInstanceId, propertyId); + if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.trace("The property {} already added to the resource instance {}", propertyId, resourceInstanceId); + resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight()); + Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate); + if (updatePropertyOfResourceInstance.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + return Either.right(updatePropertyOfResourceInstance.right().value()); + } + return Either.right(TitanOperationStatus.OK); + } + + if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.trace("After finding property value of {} on componenet instance {}", propertyId, resourceInstanceId); + return Either.right(isPropertyValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceProperty.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exist", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.trace("Before validateAndUpdatePropertyValue"); + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, allDataTypes.left().value()); + log.trace("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid(resourceInstanceId, index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.trace("Before validateAndUpdateRules"); + ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules(), innerType, allDataTypes.left().value(), isValidate); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + propertyOperation.addRulesToNewPropertyValue(propertyValueData, resourceInstanceProperty, resourceInstanceId); + + log.trace("Before adding property value to graph {}", propertyValueData); + Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, PropertyValueData.class); + log.trace("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + propertyValueData = createNodeResult.left().value(); + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus edgeResult = titanGenericDao.createEdge(resourceInstanceVertex, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + + if (!edgeResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + " in graph. status is " + edgeResult); + return Either.right(edgeResult); + } + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + return Either.left(propertyValueResult); + } else { + log.debug("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + /** + * add property to resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @param index + * @return + */ + public Either<InputValueData, TitanOperationStatus> addInputToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index) { + + Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String propertyId = resourceInstanceInput.getUniqueId(); + Either<InputsData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), propertyId, InputsData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + String valueUniqueUid = resourceInstanceInput.getValueUniqueUid(); + if (valueUniqueUid == null) { + + InputsData propertyData = findPropertyDefRes.left().value(); + + ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + + ImmutablePair<TitanOperationStatus, String> isInputValueExists = inputOperation.findInputValue(resourceInstanceId, propertyId); + if (isInputValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { + log.debug("The property {} already added to the resource insance {}", propertyId, resourceInstanceId); + resourceInstanceInput.setValueUniqueUid(isInputValueExists.getRight()); + /* + * Either<InputValueData, TitanOperationStatus> updatePropertyOfResourceInstance = updatePropertyOfResourceInstance(resourceInstanceInput, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { + * BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); + * return Either.right(updatePropertyOfResourceInstance.right().value() ); } return Either.left(updatePropertyOfResourceInstance.left().value()); + */ + } + + if (isInputValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { + log.debug("After finding input value of {} on compnent instance {}", propertyId, resourceInstanceId); + return Either.right(isInputValueExists.getLeft()); + } + + String innerType = null; + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = resourceInstanceInput.getValue(); + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propDataDef.getSchema(); + if (def == null) { + log.debug("Schema doesn't exists for property of type {}", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + log.debug("Property in Schema Definition inside property of type {} doesn't exists", type); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + innerType = propDef.getType(); + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("UpdatePropertyValueOnComponentInstance", "Failed to update property value on instance. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + } + // Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, innerType, allDataTypes.left().value()); + // log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + /*String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + }*/ + + String uniqueId = UniqueIdBuilder.buildResourceInstanceInputValueUid(resourceInstanceData.getUniqueId(), index); + InputValueData propertyValueData = new InputValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(value); + + log.debug("Before validateAndUpdateRules"); + ImmutablePair<String, Boolean> pair = propertyOperation.validateAndUpdateRules(propertyType, resourceInstanceInput.getRules(), innerType, allDataTypes.left().value(), true); + log.debug("After validateAndUpdateRules. pair = {}", pair); + if (pair.getRight() != null && pair.getRight() == false) { + BeEcompErrorManager.getInstance().logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceInput.getName(), propertyType); + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + // propertyOperation.addRulesToNewPropertyValue(propertyValueData, + // resourceInstanceInput, resourceInstanceId); + + log.debug("Before adding property value to graph {}", propertyValueData); + Either<InputValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, InputValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, propertyData, GraphEdgeLabels.INPUT_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + // TODO: change logger + log.error("Failed to associate property value {} to property {} in graph. Status is {}", uniqueId, propertyId, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> properties1 = new HashMap<String, Object>(); + + properties1.put(GraphEdgePropertiesDictionary.NAME.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getName()); + properties1.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceData.getComponentInstDataDefinition().getUniqueId()); + + createRelResult = titanGenericDao.createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.INPUT_VALUE, properties1); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + // TODO: change logger + log.error("Failed to associate resource instance {} property value {} in graph. Status is {}", resourceInstanceId, uniqueId, operationStatus); + return Either.right(operationStatus); + + } + + // inputOperation.associatePropertyToInput(resourceInstanceId, + // resourceInstanceInput.getInputId(), propertyValueData, + // resourceInstanceInput.getName()); + + return Either.left(createNodeResult.left().value()); + } else { + log.error("property value already exists."); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + + } + + @Override + public Either<ComponentInstanceAttribute, StorageOperationStatus> addAttributeValueToResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, Integer index, boolean inTransaction) { + Either<ComponentInstanceAttribute, StorageOperationStatus> result = null; + + try { + + Either<AttributeValueData, TitanOperationStatus> eitherStatus = this.addAttributeToResourceInstance(resourceInstanceAttribute, resourceInstanceId, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + AttributeValueData attributeValueData = eitherStatus.left().value(); + + ComponentInstanceAttribute attributeValueResult = attributeOperation.buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute); + log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult); + + result = Either.left(attributeValueResult); + return result; + } + } + + finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either<ComponentInstanceAttribute, StorageOperationStatus> updateAttributeValueInResourceInstance(ComponentInstanceAttribute resourceInstanceAttribute, String resourceInstanceId, boolean inTransaction) { + + Either<ComponentInstanceAttribute, StorageOperationStatus> result = null; + + try { + Either<AttributeValueData, TitanOperationStatus> eitherAttributeValue = updateAttributeOfResourceInstance(resourceInstanceAttribute, resourceInstanceId); + + if (eitherAttributeValue.isRight()) { + log.error("Failed to add attribute value {} to resource instance {} in Graph. status is {}", resourceInstanceAttribute, resourceInstanceId, eitherAttributeValue.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherAttributeValue.right().value())); + return result; + } else { + AttributeValueData attributeValueData = eitherAttributeValue.left().value(); + + ComponentInstanceAttribute attributeValueResult = attributeOperation.buildResourceInstanceAttribute(attributeValueData, resourceInstanceAttribute); + log.debug("The returned ResourceInstanceAttribute is {}", attributeValueResult); + + result = Either.left(attributeValueResult); + return result; + } + } + + finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + @Override + public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) { + return addPropertyValueToResourceInstance(resourceInstanceProperty, resourceInstanceId, true, index, inTransaction); + } + + @Override + public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance(ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean isValidate, Integer index, boolean inTransaction) { + + /// #RULES SUPPORT + /// Ignore rules received from client till support + resourceInstanceProperty.setRules(null); + /// + /// + + Either<ComponentInstanceProperty, StorageOperationStatus> result = null; + + try { + + Either<PropertyValueData, TitanOperationStatus> eitherStatus = addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, isValidate, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add property value {} to resource instance {} in Graph. status is {}", resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = propertyOperation.buildResourceInstanceProperty(propertyValueData, resourceInstanceProperty); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceProperty.getPath(), resourceInstanceProperty.getUniqueId(), resourceInstanceProperty.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<ComponentInstanceInput, StorageOperationStatus> addInputValueToResourceInstance(ComponentInstanceInput resourceInstanceInput, String resourceInstanceId, Integer index, boolean inTransaction) { + + /// #RULES SUPPORT + /// Ignore rules received from client till support + resourceInstanceInput.setRules(null); + /// + /// + + Either<ComponentInstanceInput, StorageOperationStatus> result = null; + + try { + + Either<InputValueData, TitanOperationStatus> eitherStatus = addInputToResourceInstance(resourceInstanceInput, resourceInstanceId, index); + + if (eitherStatus.isRight()) { + log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", resourceInstanceInput, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + InputValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceInput propertyValueResult = inputOperation.buildResourceInstanceInput(propertyValueData, resourceInstanceInput); + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + + Either<String, TitanOperationStatus> findDefaultValue = propertyOperation.findDefaultValueFromSecondPosition(resourceInstanceInput.getPath(), resourceInstanceInput.getUniqueId(), resourceInstanceInput.getDefaultValue()); + if (findDefaultValue.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findDefaultValue.right().value())); + return result; + } + String defaultValue = findDefaultValue.left().value(); + propertyValueResult.setDefaultValue(defaultValue); + log.debug("The returned default value in ResourceInstanceProperty is {}", defaultValue); + + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getComponentInstancesProperties(List<ComponentInstance> resourceInstances, Map<String, List<PropertyDefinition>> alreadyProcessedResources, + Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties, Map<String, ImmutablePair<ComponentInstance, Integer>> processedInstances, List<String> path) { + + List<ComponentInstanceProperty> result = new ArrayList<>(); + + for (ComponentInstance componentInstance : resourceInstances) { + + path.add(componentInstance.getUniqueId()); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> componentInstancesProperties = getComponentInstanceProperties(componentInstance, alreadyProcessedResources, resourceInstancesProperties, processedInstances, path); + if (componentInstancesProperties.isRight()) { + TitanOperationStatus status = componentInstancesProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + + List<ComponentInstanceProperty> compInstancePropertyList = componentInstancesProperties.left().value(); + if (compInstancePropertyList != null) { + result.addAll(compInstancePropertyList); + } + + String uniqueId = componentInstance.getUniqueId(); + if (false == processedInstances.containsKey(uniqueId)) { + processedInstances.put(uniqueId, new ImmutablePair<ComponentInstance, Integer>(componentInstance, path.size())); + } + path.remove(path.size() - 1); + + } + + return Either.left(result); + } + + public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getComponentInstanceProperties(ComponentInstance resourceInstance, Map<String, List<PropertyDefinition>> alreadyProcessedResources, + Map<String, List<ComponentInstanceProperty>> alreadyProcessedInstances, Map<String, ImmutablePair<ComponentInstance, Integer>> processedInstances, List<String> path) { + + // 1. Go over each instance + // 1.1 get all properties of from the parents of the instance + // 1.2 get all updated properties + // 1.3 find all instances included in the parent of this instance and + // run this method on them. + if (log.isDebugEnabled()) + log.debug("Going to update properties of resource instance {}", resourceInstance.getUniqueId()); + String resourceUid = resourceInstance.getComponentUid(); + + List<PropertyDefinition> properties = alreadyProcessedResources.get(resourceUid); + if (properties == null) { + properties = new ArrayList<>(); + TitanOperationStatus findAllRes = propertyOperation.findAllResourcePropertiesRecursively(resourceUid, properties); + if (findAllRes != TitanOperationStatus.OK) { + return Either.right(findAllRes); + } + alreadyProcessedResources.put(resourceUid, properties); + } + + if (log.isDebugEnabled()) + log.debug("After getting properties of resource {} . Number of properties is {}", resourceUid, (properties == null ? 0 : properties.size())); + List<ComponentInstanceProperty> resourceInstancePropertyList = new ArrayList<>(); + if (false == properties.isEmpty()) { + + // TODO: WE MAY HAVE INDIRECT PROPERTY VALUE ALSO IN CASE NO + // PROPERTY ON THIS COMPONENT + + // String resourceInstanceUid = resourceInstance.getUniqueId(); + + for (PropertyDefinition propertyDefinition : properties) { + + String defaultValue = propertyDefinition.getDefaultValue(); + String value = defaultValue; + String valueUid = null; + + // String propertyId = propertyDefinition.getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(propertyDefinition, value, valueUid); + + resourceInstanceProperty.setPath(cloneList(path)); + + // TODO: currently ignore constraints since they are not inuse + // and cause to error in convertion to object. + resourceInstanceProperty.setConstraints(null); + + resourceInstancePropertyList.add(resourceInstanceProperty); + + } + + } + + OriginTypeEnum originType = resourceInstance.getOriginType(); + + Either<List<ComponentInstance>, TitanOperationStatus> findInstancesUnderParentOfInstance = findInstancesUnderParentOfInstance(originType, resourceUid); + + if (findInstancesUnderParentOfInstance.isRight()) { + TitanOperationStatus status = findInstancesUnderParentOfInstance.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } + } else { + List<ComponentInstance> listOfInstances = findInstancesUnderParentOfInstance.left().value(); + Either<List<ComponentInstanceProperty>, TitanOperationStatus> componentInstancesProperties = getComponentInstancesProperties(listOfInstances, alreadyProcessedResources, alreadyProcessedInstances, processedInstances, path); + if (componentInstancesProperties.isRight()) { + TitanOperationStatus status = componentInstancesProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + } + List<ComponentInstanceProperty> currentList = componentInstancesProperties.left().value(); + if (currentList != null) { + resourceInstancePropertyList.addAll(currentList); + } + } + + return Either.left(resourceInstancePropertyList); + } + + public Either<List<ComponentInstance>, TitanOperationStatus> findInstancesUnderParentOfInstance(OriginTypeEnum originType, String resourceUid) { + + NodeTypeEnum containerNodeType = null; + NodeTypeEnum compInstNodeType = null; + + switch (originType) { + + case VF: + containerNodeType = NodeTypeEnum.Resource; + compInstNodeType = NodeTypeEnum.Resource; + break; + case SERVICE: + containerNodeType = NodeTypeEnum.Service; + compInstNodeType = NodeTypeEnum.Resource; + break; + case PRODUCT: + containerNodeType = NodeTypeEnum.Product; + compInstNodeType = NodeTypeEnum.Service; + case VFC: + case VL: + case CP: + break; + default: + break; + } + + if (containerNodeType == null || compInstNodeType == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> componentInstancesOfComponent = this.getComponentInstancesOfComponent(resourceUid, containerNodeType, compInstNodeType); + + if (componentInstancesOfComponent.isRight()) { + TitanOperationStatus status = componentInstancesOfComponent.right().value(); + log.debug("After getting instances of {} from type {}. Status is {}", resourceUid, originType, status); + return Either.right(status); + } else { + List<ComponentInstance> listOfInstances = componentInstancesOfComponent.left().value().getLeft(); + if (log.isDebugEnabled()) { + String msg = "After getting instances of {} from type {} {}."; + log.debug(msg, resourceUid, originType, (listOfInstances != null ? listOfInstances.size() : 0)); + if (log.isTraceEnabled()) + log.trace(msg, resourceUid, originType, listOfInstances); + } + return Either.left(listOfInstances); + } + + } + + private List<String> cloneList(List<String> list) { + + if (list == null) { + return null; + } + + List<String> clonedList = new ArrayList(); + clonedList.addAll(list); + + return clonedList; + } + + public Either<Map<String, Map<String, ComponentInstanceProperty>>, TitanOperationStatus> findAllPropertyValueOnInstances(Map<String, ImmutablePair<ComponentInstance, Integer>> processedInstances) { + + if (processedInstances == null) { + return Either.right(TitanOperationStatus.OK); + } + + Set<Entry<String, ImmutablePair<ComponentInstance, Integer>>> entrySet = processedInstances.entrySet(); + + Map<String, Map<String, ComponentInstanceProperty>> propertyToInstanceValue = new HashMap<>(); + + for (Entry<String, ImmutablePair<ComponentInstance, Integer>> entry : entrySet) { + + String compInstUniqueId = entry.getKey(); + + ImmutablePair<ComponentInstance, Integer> pair = entry.getValue(); + + ComponentInstance componentInstance = pair.getLeft(); + Integer level = pair.getRight(); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> propeprtyValueOnCIResult = findPropertyValueOnComponentInstance(componentInstance); + + if (propeprtyValueOnCIResult.isRight()) { + TitanOperationStatus status = propeprtyValueOnCIResult.right().value(); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + continue; + } + + List<ComponentInstanceProperty> propertyValuesOnCI = propeprtyValueOnCIResult.left().value(); + if (propeprtyValueOnCIResult != null) { + for (ComponentInstanceProperty instanceProperty : propertyValuesOnCI) { + boolean result = addPropertyValue(compInstUniqueId, instanceProperty, propertyToInstanceValue); + if (result == false) { + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + } + + } + + return Either.left(propertyToInstanceValue); + } + + private boolean addPropertyValue(String compInstUniqueId, ComponentInstanceProperty instanceProperty, Map<String, Map<String, ComponentInstanceProperty>> propertyToInstanceValue) { + + String propertyUid = instanceProperty.getUniqueId(); + + Map<String, ComponentInstanceProperty> map = propertyToInstanceValue.get(propertyUid); + if (map == null) { + map = new HashMap<>(); + propertyToInstanceValue.put(propertyUid, map); + } + + ComponentInstanceProperty putIfAbsent = map.putIfAbsent(compInstUniqueId, instanceProperty); + if (putIfAbsent != null) { + BeEcompErrorManager.getInstance().logInternalUnexpectedError("find property value", "Found 2 values on the same instance", ErrorSeverity.ERROR); + return false; + } + + return true; + + } + + private boolean addInputValue(String compInstUniqueId, ComponentInstanceInput instanceProperty, Map<String, Map<String, ComponentInstanceInput>> propertyToInstanceValue) { + + String propertyUid = instanceProperty.getUniqueId(); + + Map<String, ComponentInstanceInput> map = propertyToInstanceValue.get(propertyUid); + if (map == null) { + map = new HashMap<>(); + propertyToInstanceValue.put(propertyUid, map); + } + + ComponentInstanceInput putIfAbsent = map.putIfAbsent(compInstUniqueId, instanceProperty); + if (putIfAbsent != null) { + BeEcompErrorManager.getInstance().logInternalUnexpectedError("find property value", "Found 2 values on the same instance", ErrorSeverity.ERROR); + return false; + } + + return true; + + } + + private Either<List<ComponentInstanceProperty>, TitanOperationStatus> findPropertyValueOnComponentInstance(ComponentInstance componentInstance) { + String resourceInstanceUid = componentInstance.getUniqueId(); + OriginTypeEnum originType = componentInstance.getOriginType(); + + NodeTypeEnum instanceNodeType = findInstanceNodeTypeEnumFromOriginType(originType); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesResult = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, instanceNodeType); + + log.debug("After fetching property under resource instance {}", resourceInstanceUid); + if (propertyValuesResult.isRight()) { + TitanOperationStatus status = propertyValuesResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } + return Either.right(TitanOperationStatus.OK); + } + + return Either.left(propertyValuesResult.left().value()); + + } + + private NodeTypeEnum findInstanceNodeTypeEnumFromOriginType(OriginTypeEnum originType) { + NodeTypeEnum nodeType = NodeTypeEnum.ResourceInstance; + switch (originType) { + case SERVICE: + nodeType = NodeTypeEnum.ResourceInstance; + break; + default: + break; + } + + return nodeType; + } + + /** + * add capability property values to resource instance + * + * @param resourceInstanceId + * @param capability + * @param isNewlyCreatedResourceInstance + * @return + */ + public Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> addCapabilityPropertyValuesToResourceInstance(String resourceInstanceId, CapabilityDefinition capability, boolean isNewlyCreatedResourceInstance) { + log.debug("Before adding capability property values to resource instance {}.", resourceInstanceId); + TitanOperationStatus error = null; + + Either<Map<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> addCapInstWithPropertiesRes = capabilityInstanceOperation.createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(resourceInstanceId, + capability.getUniqueId(), capability.getName(), capability.getProperties(), !isNewlyCreatedResourceInstance); + if (addCapInstWithPropertiesRes.isRight()) { + error = addCapInstWithPropertiesRes.right().value(); + log.debug("Failed to assotiate capability instance to resource instance {}. Status is {}", resourceInstanceId, error); + } + log.debug("After adding capability property values to resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(addCapInstWithPropertiesRes.left().value()); + } + return Either.right(error); + } + + public TitanOperationStatus addCapabilityPropertyValuesToResourceInstance(TitanVertex resourceInstanceVertex, String resourceInstanceId, CapabilityDefinition capability, boolean isNewlyCreatedResourceInstance) { + log.trace("Before adding capability property values to resource instance {}.", resourceInstanceId); + TitanOperationStatus error = TitanOperationStatus.OK; + + TitanOperationStatus addCapInstWithPropertiesRes = capabilityInstanceOperation.createCapabilityInstanceOfCapabilityWithPropertyValuesForResourceInstance(resourceInstanceVertex, resourceInstanceId, capability.getUniqueId(), + capability.getName(), capability.getProperties(), !isNewlyCreatedResourceInstance); + if (!addCapInstWithPropertiesRes.equals(TitanOperationStatus.OK)) { + error = addCapInstWithPropertiesRes; + log.debug("Failed to assotiate capability instance to resource instance {} . status is {}", resourceInstanceId, error); + } + log.debug("After adding capability property values to resource instance {}. Status is {}", resourceInstanceId, error); + + return error; + } + + /** + * update capability property values of capability + * + * @param resourceInstanceId + * @param capabilityId + * @param propertyValues + * @return + */ + public Either<List<PropertyValueData>, TitanOperationStatus> updateCapabilityPropertyValuesOfResourceInstance(String resourceInstanceId, String capabilityId, List<ComponentInstanceProperty> propertyValues) { + log.debug("Before updating property values of capability {} of resource instance {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Either<List<PropertyValueData>, TitanOperationStatus> updateCapabilityPropertyValuesRes = capabilityInstanceOperation.updateCapabilityPropertyValues(resourceInstanceId, capabilityId, propertyValues); + if (updateCapabilityPropertyValuesRes.isRight()) { + error = updateCapabilityPropertyValuesRes.right().value(); + log.debug("Failed to update property values of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + } + log.debug("After updating property values of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + if (error == null) { + return Either.left(updateCapabilityPropertyValuesRes.left().value()); + } + return Either.right(error); + } + + /** + * delete property values of capability from resource instance + * + * @param capabilityId + * @param resourceInstanceId + * @return + */ + public Either<CapabilityInstData, TitanOperationStatus> deletePropertyValuesOfCapabilityFromResourceInstance(String capabilityId, String resourceInstanceId) { + log.debug("Before deleting property values of capability {} from resource instance {}.", capabilityId, resourceInstanceId); + TitanOperationStatus error = null; + Either<CapabilityInstData, TitanOperationStatus> deleteCapInstWithPropertiesRes = null; + Either<CapabilityInstData, TitanOperationStatus> getCapInstByCapabilityRes = capabilityInstanceOperation.getCapabilityInstanceOfCapabilityOfResourceInstance(resourceInstanceId, capabilityId); + if (getCapInstByCapabilityRes.isRight()) { + error = getCapInstByCapabilityRes.right().value(); + log.debug("Failed to retrieve capability instance of capability {} of resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + } + if (error == null) { + String capabilityInstanceId = getCapInstByCapabilityRes.left().value().getUniqueId(); + deleteCapInstWithPropertiesRes = capabilityInstanceOperation.deleteCapabilityInstanceFromResourceInstance(resourceInstanceId, capabilityInstanceId); + if (deleteCapInstWithPropertiesRes.isRight()) { + error = deleteCapInstWithPropertiesRes.right().value(); + log.debug("Failed to delete capability instance {} to resource instance {}. Status is {}", capabilityInstanceId, resourceInstanceId, error); + } + } + log.debug("After deleting property values of capability {} from resource instance {}. Status is {}", capabilityId, resourceInstanceId, error); + if (error == null) { + return Either.left(deleteCapInstWithPropertiesRes.left().value()); + } + return Either.right(error); + } + + /** + * clone capability instances of resource instance + * + * @param createdComponentInstance + * @param resourceInstance + * @return + */ + private Either<Map<ImmutablePair<CapabilityInstData, GraphEdge>, List<PropertyValueData>>, TitanOperationStatus> cloneCapabilityInstancesOfResourceInstance(ComponentInstanceData createdComponentInstance, ComponentInstance resourceInstance) { + TitanOperationStatus error = null; + String resourceInstanceId = resourceInstance.getUniqueId(); + log.debug("Before cloning of capability instances of resource instance {}.", resourceInstanceId); + + Map<ImmutablePair<CapabilityInstData, GraphEdge>, List<PropertyValueData>> result = new HashMap<>(); + Either<ImmutablePair<CapabilityInstData, List<PropertyValueData>>, TitanOperationStatus> cloneAssociateCIWithPropertyValuesRes; + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getAllCapabilityInstancesRes = capabilityInstanceOperation.getAllCapabilityInstancesOfResourceInstance(resourceInstanceId); + if (getAllCapabilityInstancesRes.isRight() && !getAllCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllCapabilityInstancesRes.right().value(); + log.debug("Failed to get capability instances of component instance {}. Status is {}", resourceInstanceId, error); + } + if (getAllCapabilityInstancesRes.isLeft()) { + List<ImmutablePair<CapabilityInstData, GraphEdge>> capabilityInstances = getAllCapabilityInstancesRes.left().value(); + Map<String, List<CapabilityDefinition>> allCapabilitiesMap = resourceInstance.getCapabilities(); + List<CapabilityDefinition> allCapabilitiesList = new ArrayList<>(); + for (List<CapabilityDefinition> curList : allCapabilitiesMap.values()) { + allCapabilitiesList.addAll(curList); + } + Map<String, CapabilityDefinition> capabilities = allCapabilitiesList.stream().collect(Collectors.toMap(CapabilityDefinition::getUniqueId, Function.identity())); + String propertyName = GraphPropertiesDictionary.CAPABILITY_ID.getProperty(); + for (ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstPair : capabilityInstances) { + String capabilityId = (String) capabilityInstPair.getRight().getProperties().get(propertyName); + CapabilityDefinition relatedCapability = capabilities.get(capabilityId); + cloneAssociateCIWithPropertyValuesRes = capabilityInstanceOperation.cloneAssociateCapabilityInstanceWithPropertyValues(createdComponentInstance, relatedCapability, capabilityInstPair); + if (cloneAssociateCIWithPropertyValuesRes.isRight()) { + error = cloneAssociateCIWithPropertyValuesRes.right().value(); + log.debug("Failed to clone capability instances {} of component instance {}. Status is {}", capabilityInstPair.getLeft().getUniqueId(), resourceInstanceId, error); + break; + } else { + result.put(new ImmutablePair<CapabilityInstData, GraphEdge>(cloneAssociateCIWithPropertyValuesRes.left().value().getLeft(), capabilityInstPair.getRight()), cloneAssociateCIWithPropertyValuesRes.left().value().getRight()); + } + } + } + log.debug("After cloning of capability instance of resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(result); + } + return Either.right(error); + } + + private Either<List<ImmutablePair<TitanVertex, GraphEdge>>, TitanOperationStatus> cloneCapabilityInstancesOfResourceInstance(TitanVertex componentInstanceVertex, ComponentInstance resourceInstance) { + TitanOperationStatus error = null; + String resourceInstanceId = resourceInstance.getUniqueId(); + log.debug("Before cloning of capability instances of resource instance {}.", resourceInstanceId); + + Either<TitanVertex, TitanOperationStatus> cloneAssociateCIWithPropertyValuesRes = null; + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getAllCapabilityInstancesRes = capabilityInstanceOperation.getAllCapabilityInstancesOfResourceInstance(resourceInstanceId); + if (getAllCapabilityInstancesRes.isRight() && !getAllCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getAllCapabilityInstancesRes.right().value(); + log.debug("Failed to get capability instances of component instance {}. status is {}", resourceInstanceId, error); + } + List<ImmutablePair<TitanVertex, GraphEdge>> list = new ArrayList<>(); + if (getAllCapabilityInstancesRes.isLeft()) { + List<ImmutablePair<CapabilityInstData, GraphEdge>> capabilityInstances = getAllCapabilityInstancesRes.left().value(); + Map<String, List<CapabilityDefinition>> allCapabilitiesMap = resourceInstance.getCapabilities(); + List<CapabilityDefinition> allCapabilitiesList = new ArrayList<>(); + for (List<CapabilityDefinition> curList : allCapabilitiesMap.values()) { + allCapabilitiesList.addAll(curList); + } + Map<String, CapabilityDefinition> capabilities = allCapabilitiesList.stream().collect(Collectors.toMap(CapabilityDefinition::getUniqueId, Function.identity())); + String propertyName = GraphPropertiesDictionary.CAPABILITY_ID.getProperty(); + for (ImmutablePair<CapabilityInstData, GraphEdge> capabilityInstPair : capabilityInstances) { + String capabilityId = (String) capabilityInstPair.getRight().getProperties().get(propertyName); + CapabilityDefinition relatedCapability = capabilities.get(capabilityId); + cloneAssociateCIWithPropertyValuesRes = capabilityInstanceOperation.cloneAssociateCapabilityInstanceWithPropertyValues(componentInstanceVertex, relatedCapability, capabilityInstPair); + if (cloneAssociateCIWithPropertyValuesRes.isRight()) { + error = cloneAssociateCIWithPropertyValuesRes.right().value(); + log.debug("Failed to clone capability instances {} of component instance {}. status is {}", capabilityInstPair.getLeft().getUniqueId(), resourceInstanceId, error); + break; + } else { + list.add(new ImmutablePair<TitanVertex, GraphEdge>(cloneAssociateCIWithPropertyValuesRes.left().value(), capabilityInstPair.right)); + } + } + } + log.debug("After cloning of capability instance of resource instance {}. Status is {}", resourceInstanceId, error); + if (error == null) { + return Either.left(list); + } + return Either.right(error); + } + + public Either<List<ComponentInstance>, StorageOperationStatus> getAllComponentInstancesMetadataOnly(String componentId, NodeTypeEnum containerNodeType) { + + List<ComponentInstance> componentInstancesResult = new ArrayList<ComponentInstance>(); + Either<List<ComponentInstance>, StorageOperationStatus> result = Either.left(componentInstancesResult); + + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> resourceInstancesRes = getAllComponentInstanceFromGraph(componentId, containerNodeType, false); + + if (resourceInstancesRes.isRight()) { + + if (log.isDebugEnabled()) { + log.debug("Resource instance was found under service {} . status is {} ", componentId, resourceInstancesRes.right().value()); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceInstancesRes.right().value())); + } + + List<ImmutablePair<ComponentInstanceData, GraphEdge>> resourceInstances = resourceInstancesRes.left().value(); + if (resourceInstances != null && false == resourceInstances.isEmpty()) { + + for (ImmutablePair<ComponentInstanceData, GraphEdge> immutablePair : resourceInstances) { + ComponentInstanceData resourceInstanceData = immutablePair.getKey(); + if (log.isDebugEnabled()) { + log.debug("Going to fetch the relationships of resource instance {}", resourceInstanceData); + } + componentInstancesResult.add(new ComponentInstance(resourceInstanceData.getComponentInstDataDefinition())); + + } + } + + return result; + } + + public Either<List<CapabilityDefinition>, TitanOperationStatus> updateCapDefPropertyValues(ComponentInstance componentInstance, List<CapabilityDefinition> capabilityDefList) { + String componentInstanceId = componentInstance.getUniqueId(); + log.debug("Before updating property values of capabilities of component istance {}.", componentInstanceId); + TitanOperationStatus error = null; + NodeTypeEnum nodeType = NodeTypeEnum.getByNameIgnoreCase(componentInstance.getOriginType().getInstanceType().trim()); + + log.debug("Before getting all capability instances of component istance {}.", componentInstanceId); + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> getCapabilityInstancesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), componentInstanceId, GraphEdgeLabels.CAPABILITY_INST, + NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (getCapabilityInstancesRes.isRight() && !getCapabilityInstancesRes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + error = getCapabilityInstancesRes.right().value(); + log.debug("Failed to retrieve capability Instances of resource instance {}. Status is {}", componentInstance.getName(), error); + } + log.debug("After getting all capability instances of component istance {}. Status is {}", componentInstanceId, error); + Map<String, Map<String, PropertyValueData>> overridedCapabilitiesHM = new HashMap<>(); + if (getCapabilityInstancesRes.isLeft()) { + List<ImmutablePair<CapabilityInstData, GraphEdge>> capabilityInstDataPair = getCapabilityInstancesRes.left().value(); + + for (ImmutablePair<CapabilityInstData, GraphEdge> curCapabilityPair : capabilityInstDataPair) { + CapabilityInstData curCapabilityInst = curCapabilityPair.getLeft(); + String curCapInstUid = curCapabilityInst.getUniqueId(); + + log.debug("Before getting all property values of capability instance {} of component istance {}.", curCapInstUid, componentInstanceId); + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> getOverridedPropertyValuesRes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curCapabilityInst.getLabel())), + curCapInstUid, GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + if (getOverridedPropertyValuesRes.isRight()) { + error = getOverridedPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property values of capability instance {}. Status is {}", curCapInstUid, error); + } + + log.debug("After getting all property values of capability instance {} of component istance {}. Status is {}", curCapInstUid, componentInstanceId, error); + Map<String, PropertyValueData> overridedPropertyValuesHM = new HashMap<>(); + List<ImmutablePair<PropertyValueData, GraphEdge>> overridedPropertyValues = getOverridedPropertyValuesRes.left().value(); + for (ImmutablePair<PropertyValueData, GraphEdge> curPropertyValuePair : overridedPropertyValues) { + PropertyValueData curPropertyValue = curPropertyValuePair.getLeft(); + String propertyValueUid = curPropertyValue.getUniqueId(); + log.debug("Before getting property related to property value {} of capability instance {} of component istance {}.", propertyValueUid, curCapInstUid, componentInstanceId); + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> getPropertyDataRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.getByName(curPropertyValue.getLabel())), propertyValueUid, + GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (getPropertyDataRes.isRight()) { + error = getOverridedPropertyValuesRes.right().value(); + log.debug("Failed to retrieve property of property value {} Status is {}", propertyValueUid, error); + } + + if (log.isDebugEnabled()) { + log.debug("After getting property related to property value {} of capability instance {} of component istance {}. Status is {}", propertyValueUid, curCapInstUid, componentInstanceId, error); + } + PropertyData propertyData = getPropertyDataRes.left().value().getLeft(); + overridedPropertyValuesHM.put((String) propertyData.getUniqueId(), curPropertyValue); + } + overridedCapabilitiesHM.put((String) curCapabilityPair.getRight().getProperties().get(GraphPropertiesDictionary.CAPABILITY_ID.getProperty()), overridedPropertyValuesHM); + } + } + if (error == null && !overridedCapabilitiesHM.isEmpty()) { + updateCapabilityPropertyValues(componentInstance.getCapabilities(), capabilityDefList, overridedCapabilitiesHM); + } + log.debug("After updating property values of capabilities of component istance {}. Status is {}", componentInstanceId, error); + if (error == null) { + return Either.left(capabilityDefList); + } + return Either.right(error); + } + + private void updateCapabilityPropertyValues(Map<String, List<CapabilityDefinition>> capabilitiesOfRI, List<CapabilityDefinition> capabilitiesOfContainer, Map<String, Map<String, PropertyValueData>> overridedCapabilitiesHM) { + + capabilitiesOfContainer.stream().filter(capability -> overridedCapabilitiesHM.containsKey(capability.getUniqueId())).forEach(capability -> { + boolean updateProperties = false; + for (ComponentInstanceProperty property : capability.getProperties()) { + if (overridedCapabilitiesHM.get(capability.getUniqueId()).containsKey(property.getUniqueId())) { + property.setValue(overridedCapabilitiesHM.get(capability.getUniqueId()).get(property.getUniqueId()).getValue()); + property.setValueUniqueUid(overridedCapabilitiesHM.get(capability.getUniqueId()).get(property.getUniqueId()).getUniqueId()); + updateProperties = true; + } + } + if (updateProperties) { + capabilitiesOfRI.get(capability.getType()).get(0).setProperties(capability.getProperties()); + } + }); + } + + @Override + public Either<ComponentInstanceInput, StorageOperationStatus> updateInputValueInResourceInstance(ComponentInstanceInput input, String resourceInstanceId, boolean b) { + // TODO Auto-generated method stub + return null; + } + + public Either<Map<String, ArtifactDefinition>, StorageOperationStatus> fetchCIEnvArtifacts(String componentInstanceId) { + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> result = artifactOperation.getArtifacts(componentInstanceId, NodeTypeEnum.ResourceInstance, true, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + if (result.isRight() && result.right().value() == StorageOperationStatus.NOT_FOUND) + return Either.right(StorageOperationStatus.OK); + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java new file mode 100644 index 0000000000..b243c6ea4d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java @@ -0,0 +1,2886 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.time.Duration; +import java.time.Instant; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.QueryType; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanGraphClient; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.ICapabilityOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IRequirementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ProductMetadataData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.be.workers.Job; +import org.openecomp.sdc.be.workers.Manager; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.StreamUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.beans.factory.annotation.Autowired; + +import com.google.common.collect.ImmutableSet; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanGraphQuery; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public abstract class ComponentOperation { + private static Logger log = LoggerFactory.getLogger(ComponentOperation.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + + @Autowired + protected IArtifactOperation artifactOperation; + + @Autowired + protected IElementOperation elementOperation; + + @Autowired + protected ICapabilityOperation capabilityOperation; + + @Autowired + protected IRequirementOperation requirementOperation; + + @Autowired + protected ComponentInstanceOperation componentInstanceOperation; + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + protected InputsOperation inputOperation; + + @Autowired + protected IAdditionalInformationOperation additionalInformationOperation; + + @Autowired + protected GroupOperation groupOperation; + + @Autowired + protected InputsOperation inputsOperation; + + @Autowired + protected ApplicationDataTypeCache applicationDataTypeCache; + + @Autowired + private ComponentCache componentCache; + + private static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1"); + + protected Gson prettyJson = new GsonBuilder().setPrettyPrinting().create(); + + protected Either<List<TagData>, StorageOperationStatus> createNewTagsList(List<String> tags) { + + List<TagData> existingTags = new ArrayList<TagData>(); + List<TagData> tagsToCreate = new ArrayList<TagData>(); + Either<List<TagData>, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, TagData.class); + + if ((either.isRight()) && (either.right().value() != TitanOperationStatus.NOT_FOUND)) { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } else if (either.isLeft()) { + existingTags = either.left().value(); + } + + for (String tagName : tags) { + TagData tag = new TagData(tagName); + if ((existingTags == null) || (!existingTags.contains(tag))) { + tagsToCreate.add(tag); + } + } + return Either.left(tagsToCreate); + + } + + protected StorageOperationStatus createTagNodesOnGraph(List<TagData> tagsToCreate) { + StorageOperationStatus result = StorageOperationStatus.OK; + // In order to avoid duplicate tags + tagsToCreate = ImmutableSet.copyOf(tagsToCreate).asList(); + if (tagsToCreate != null && false == tagsToCreate.isEmpty()) { + for (TagData tagData : tagsToCreate) { + log.debug("Before creating tag {}", tagData); + Either<TagData, TitanOperationStatus> createTagResult = titanGenericDao.createNode(tagData, TagData.class); + if (createTagResult.isRight()) { + TitanOperationStatus status = createTagResult.right().value(); + log.error("Cannot create {} in the graph. Status is {}", tagData, status); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + + } + log.debug("After creating tag {}", tagData); + } + } + return result; + } + + public Either<Component, StorageOperationStatus> getLatestComponentByUuid(NodeTypeEnum nodeType, String uuid) { + Either<Component, StorageOperationStatus> getComponentResult = null; + Either<ComponentMetadataData, StorageOperationStatus> latestComponentMetadataRes = getLatestComponentMetadataByUuid(nodeType, uuid); + if (latestComponentMetadataRes.isRight()) { + getComponentResult = Either.right(latestComponentMetadataRes.right().value()); + } + if (getComponentResult == null) { + ComponentMetadataData latestVersion = latestComponentMetadataRes.left().value(); + String id = latestVersion.getMetadataDataDefinition().getUniqueId(); + Either<Component, StorageOperationStatus> component = getComponent(id, false); + if (component.isRight()) { + log.debug("Couldn't fetch component with type {} and id {}, error: {}", nodeType, id, component.right().value()); + getComponentResult = Either.right(component.right().value()); + } else { + getComponentResult = Either.left(component.left().value()); + } + } + return getComponentResult; + } + + public Either<ComponentMetadataData, StorageOperationStatus> getLatestComponentMetadataByUuid(NodeTypeEnum nodeType, String uuid) { + + Either<ComponentMetadataData, StorageOperationStatus> getComponentResult = null; + List<ComponentMetadataData> latestVersionList = null; + ComponentMetadataData latestVersion = null; + + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either<List<ComponentMetadataData>, TitanOperationStatus> getComponentEither = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, ComponentMetadataData.class); + if (getComponentEither.isRight()) { + log.debug("Couldn't fetch metadata for component with type {} and uuid {}, error: {}", nodeType, uuid, getComponentEither.right().value()); + getComponentResult = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getComponentEither.right().value())); + + } + if (getComponentResult == null) { + latestVersionList = getComponentEither.left().value(); + if (latestVersionList.isEmpty()) { + log.debug("Component with type {} and uuid {} was not found", nodeType, uuid); + getComponentResult = Either.right(StorageOperationStatus.NOT_FOUND); + } + } + if (getComponentResult == null) { + latestVersion = latestVersionList.size() == 1 ? latestVersionList.get(0) + : latestVersionList.stream().max((c1, c2) -> Double.compare(Double.parseDouble(c1.getMetadataDataDefinition().getVersion()), Double.parseDouble(c2.getMetadataDataDefinition().getVersion()))).get(); + getComponentResult = Either.left(latestVersion); + } + return getComponentResult; + } + + public <T extends GraphNode> Either<T, StorageOperationStatus> getComponentByLabelAndId(String uniqueId, NodeTypeEnum nodeType, Class<T> clazz) { + + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId); + Either<List<T>, TitanOperationStatus> getResponse = titanGenericDao.getByCriteria(nodeType, propertiesToMatch, clazz); + if (getResponse.isRight()) { + log.debug("Couldn't fetch component with type {} and unique id {}, error: {}", nodeType, uniqueId, getResponse.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value())); + + } + List<T> serviceDataList = getResponse.left().value(); + if (serviceDataList.isEmpty()) { + log.debug("Component with type {} and unique id {} was not found", nodeType, uniqueId); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + T serviceData = serviceDataList.get(0); + return Either.left(serviceData); + } + + // protected <T extends GraphNode> Either<T, StorageOperationStatus> + // getComponentByLabelAndId_tx(String uniqueId, NodeTypeEnum nodeType, + // Class<T> clazz) { + // + // Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + // propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(nodeType), + // uniqueId); + // Either<List<T>, TitanOperationStatus> getResponse = + // titanGenericDao.getByCriteria_tx(nodeType, propertiesToMatch, clazz); + // if (getResponse.isRight()) { + // log.debug("Couldn't fetch component with type {} and unique id {}, error: + // {}", nodeType, uniqueId, getResponse.right().value()); + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getResponse.right().value())); + // + // } + // List<T> serviceDataList = getResponse.left().value(); + // if (serviceDataList.isEmpty()) { + // log.debug("Component with type {} and unique id {} was not found", + // nodeType, uniqueId); + // return Either.right(StorageOperationStatus.NOT_FOUND); + // } + // T serviceData = serviceDataList.get(0); + // return Either.left(serviceData); + // } + + /** + * + * @param component + * @param uniqueId + * @param nodeType + * @return + */ + protected TitanOperationStatus setComponentCreatorFromGraph(Component component, String uniqueId, NodeTypeEnum nodeType) { + Either<ImmutablePair<UserData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.CREATOR, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair<UserData, GraphEdge> value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + if (log.isDebugEnabled()) + log.debug("Build resource : set creator userId to {}", userData.getUserId()); + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {} ", fullName); + component.setCreatorUserId(userData.getUserId()); + component.setCreatorFullName(fullName); + + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus setComponentLastModifierFromGraph(Component component, String uniqueId, NodeTypeEnum nodeType) { + + Either<ImmutablePair<UserData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.LAST_MODIFIER, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair<UserData, GraphEdge> value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier userId to {}", userData.getUserId()); + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {}", fullName); + component.setLastUpdaterUserId(userData.getUserId()); + component.setLastUpdaterFullName(fullName); + + return TitanOperationStatus.OK; + } + + /** + * + * @param userData + * @return + */ + protected String buildFullName(UserData userData) { + + String fullName = userData.getFirstName(); + if (fullName == null) { + fullName = ""; + } else { + fullName = fullName + " "; + } + String lastName = userData.getLastName(); + if (lastName != null) { + fullName += lastName; + } + return fullName; + } + + protected Either<UserData, TitanOperationStatus> findUser(String userId) { + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + Either<UserData, TitanOperationStatus> findUser = titanGenericDao.getNode(key, userId, UserData.class); + return findUser; + } + + protected Either<TitanVertex, TitanOperationStatus> findUserVertex(String userId) { + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + return titanGenericDao.getVertexByProperty(key, userId); + } + + protected Either<GroupingData, TitanOperationStatus> findGrouping(NodeTypeEnum nodeType, String groupingId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either<GroupingData, TitanOperationStatus> findGrouping = titanGenericDao.getNode(key, groupingId, GroupingData.class); + return findGrouping; + } + + protected Either<SubCategoryData, TitanOperationStatus> findSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either<SubCategoryData, TitanOperationStatus> findSubCategory = titanGenericDao.getNode(key, subCategoryId, SubCategoryData.class); + return findSubCategory; + } + + protected Either<CategoryData, TitanOperationStatus> findCategory(NodeTypeEnum nodeType, String categoryId) { + String key = UniqueIdBuilder.getKeyByNodeType(nodeType); + Either<CategoryData, TitanOperationStatus> findCategory = titanGenericDao.getNode(key, categoryId, CategoryData.class); + return findCategory; + } + + protected TitanOperationStatus associateMetadataToComponent(ComponentMetadataData componentData, UserData userData, UserData updater, CategoryData categoryData, List<ResourceMetadataData> derivedResources) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), componentData.getMetadataDataDefinition().getState()); + Either<GraphRelation, TitanOperationStatus> result = titanGenericDao.createRelation(updater, componentData, GraphEdgeLabels.STATE, props); + log.debug("After associating user {} to component {}. Edge type is {}", updater, componentData.getUniqueId(), GraphEdgeLabels.STATE); + if (result.isRight()) { + return result.right().value(); + } + + result = titanGenericDao.createRelation(updater, componentData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to component {}. Edge type is {}", updater, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (result.isRight()) { + log.error("Failed to associate user " + updater + " to component " + componentData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + return result.right().value(); + } + + result = titanGenericDao.createRelation(userData, componentData, GraphEdgeLabels.CREATOR, null); + log.debug("After associating user {} to component {}. Edge type is {}", userData, componentData.getUniqueId(), GraphEdgeLabels.CREATOR); + if (result.isRight()) { + log.error("Failed to associate user " + userData + " to component " + componentData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.CREATOR); + return result.right().value(); + } + + if (derivedResources != null) { + for (ResourceMetadataData derivedResource : derivedResources) { + log.debug("After associating component {} to parent component {}. Egde type is {}", componentData.getUniqueId(), derivedResource.getUniqueId(), GraphEdgeLabels.DERIVED_FROM); + result = titanGenericDao.createRelation(componentData, derivedResource, GraphEdgeLabels.DERIVED_FROM, null); + if (result.isRight()) { + log.error("Failed to associate user {} to component {}. Edge type is {}", userData, componentData.getUniqueId(), GraphEdgeLabels.CREATOR); + return result.right().value(); + } + } + } + + if (categoryData != null) { + result = titanGenericDao.createRelation(componentData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating component {} to category {}. Edge type is {}", componentData.getUniqueId(), categoryData, GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate component {} to category {}. Edge type is {}", componentData.getUniqueId(), categoryData, GraphEdgeLabels.CATEGORY); + return result.right().value(); + } + } + + return TitanOperationStatus.OK; + } + + protected StorageOperationStatus associateArtifactsToComponent(NodeTypeEnum nodeType, ComponentMetadataData componentData, Map<String, ArtifactDefinition> artifacts) { + + if (artifacts != null) { + for (Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either<ArtifactDefinition, StorageOperationStatus> addArifactToResource = Either.left(artifactDefinition); + // if ((artifactDefinition.getUniqueId() != null) && + // !artifactDefinition.getUniqueId().isEmpty()) { + addArifactToResource = artifactOperation.addArifactToComponent(artifactDefinition, (String) componentData.getUniqueId(), nodeType, false, true); + // } + + if (addArifactToResource.isRight()) { + return addArifactToResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + + } + + protected Either<Boolean, StorageOperationStatus> validateResourceNameUniqueness(String name, Map<String, Object> hasProps, Map<String, Object> hasNotProps, TitanGenericDao titanGenericDao) { + if (hasProps == null) { + hasProps = new HashMap<String, Object>(); + } + String normalizedName = ValidationUtils.normaliseComponentName(name); + hasProps.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either<List<ResourceMetadataData>, TitanOperationStatus> resources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, hasProps, hasNotProps, ResourceMetadataData.class); + if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get resources from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value())); + } + List<ResourceMetadataData> resourceList = (resources.isLeft() ? resources.left().value() : null); + if (resourceList != null && resourceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ResourceMetadataData resourceData : resourceList) { + builder.append(resourceData.getUniqueId() + "|"); + } + log.debug("resources with property name: {} exists in graph. Found {}", name, builder.toString()); + } + return Either.left(false); + } else { + log.debug("resources with property name:" + name + " does not exists in graph"); + return Either.left(true); + } + + } + + protected Either<Boolean, StorageOperationStatus> validateToscaResourceNameUniqueness(String name, TitanGenericDao titanGenericDao) { + Map<String, Object> properties = new HashMap<>(); + + properties.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), name); + + Either<List<ResourceMetadataData>, TitanOperationStatus> resources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, properties, ResourceMetadataData.class); + if (resources.isRight() && resources.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get resources from graph with property name:" + name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resources.right().value())); + } + List<ResourceMetadataData> resourceList = (resources.isLeft() ? resources.left().value() : null); + if (resourceList != null && resourceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ResourceMetadataData resourceData : resourceList) { + builder.append(resourceData.getUniqueId() + "|"); + } + log.debug("resources with property name:" + name + " exists in graph. found " + builder.toString()); + } + return Either.left(false); + } else { + log.debug("resources with property name: {} dows not exists in the graph", name); + return Either.left(true); + } + + } + + protected Either<Boolean, StorageOperationStatus> validateServiceNameUniqueness(String name, TitanGenericDao titanGenericDao) { + Map<String, Object> properties = new HashMap<>(); + String normalizedName = ValidationUtils.normaliseComponentName(name); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either<List<ServiceMetadataData>, TitanOperationStatus> services = titanGenericDao.getByCriteria(NodeTypeEnum.Service, properties, ServiceMetadataData.class); + if (services.isRight() && services.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get services from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(services.right().value())); + } + List<ServiceMetadataData> serviceList = (services.isLeft() ? services.left().value() : null); + if (serviceList != null && serviceList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ServiceMetadataData serviceData : serviceList) { + builder.append(serviceData.getUniqueId() + "|"); + } + log.debug("Service with property name: {} exists in graph. Found {}", name, builder.toString()); + } + + return Either.left(false); + } else { + log.debug("Service with property name: {} dows not exists in graph", name); + return Either.left(true); + } + } + + protected Either<Boolean, StorageOperationStatus> validateComponentNameUniqueness(String name, TitanGenericDao titanGenericDao, NodeTypeEnum type) { + Map<String, Object> properties = new HashMap<>(); + String normalizedName = ValidationUtils.normaliseComponentName(name); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + + Either<List<ComponentMetadataData>, TitanOperationStatus> components = titanGenericDao.getByCriteria(type, properties, ComponentMetadataData.class); + if (components.isRight() && components.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("failed to get components from graph with property name: {}", name); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(components.right().value())); + } + List<ComponentMetadataData> componentList = (components.isLeft() ? components.left().value() : null); + if (componentList != null && componentList.size() > 0) { + if (log.isDebugEnabled()) { + StringBuilder builder = new StringBuilder(); + for (ComponentMetadataData componentData : componentList) { + builder.append(componentData.getUniqueId() + "|"); + } + log.debug("Component with property name: {} exists in graph. Found {}", name, builder.toString()); + } + + return Either.left(false); + } else { + log.debug("Component with property name: {} does not exists in graph", name); + return Either.left(true); + } + } + + // protected TitanOperationStatus setComponentCategoryFromGraph(String + // uniqueId, Component component, TitanGenericDao titanGenericDao, + // NodeTypeEnum categoryType) { + // + // Either<List<ImmutablePair<CategoryData, GraphEdge>>, + // TitanOperationStatus> parentNode = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + // uniqueId, GraphEdgeLabels.CATEGORY, categoryType, + // CategoryData.class); + // if (parentNode.isRight()) { + // return parentNode.right().value(); + // } + // + // List<ImmutablePair<CategoryData, GraphEdge>> listValue = + // parentNode.left().value(); + // log.debug("Result after looking for category nodes pointed by resource " + // + uniqueId + ". status is " + listValue); + // if (listValue.size() > 1) { + // log.error("Multiple edges foud between resource " + uniqueId + " to + // category nodes."); + // } + // ImmutablePair<CategoryData, GraphEdge> value = listValue.get(0); + // log.debug("Found parent node {}", value); + // + // CategoryData categoryData = value.getKey(); + // String categoryStr = null; + // if + // (NodeTypeEnum.ResourceCategory.name().equalsIgnoreCase(categoryData.getLabel())) + // { + // StringBuilder sb = new StringBuilder(); + // sb.append(((ResourceCategoryData) categoryData).getCategoryName()); + // sb.append("/"); + // sb.append(categoryData.getName()); + // categoryStr = sb.toString(); + // } else { + // categoryStr = categoryData.getName(); + // } + // + // component.setCategory(categoryStr); + // return TitanOperationStatus.OK; + // } + + protected StorageOperationStatus setArtifactFromGraph(String uniqueId, Component component, NodeTypeEnum type, IArtifactOperation artifactOperation) { + StorageOperationStatus result = StorageOperationStatus.OK; + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(uniqueId, type, true); + if (artifacts.isRight()) { + result = artifacts.right().value(); + } else { + // component.setArtifacts(artifacts.left().value()); + createSpecificArtifactList(component, artifacts.left().value()); + } + return result; + } + + protected Component createSpecificArtifactList(Component component, Map<String, ArtifactDefinition> artifacts) { + + if (artifacts != null) { + Map<String, ArtifactDefinition> deploymentArtifacts = new HashMap<>(); + Map<String, ArtifactDefinition> serviceApiArtifacts = new HashMap<>(); + Map<String, ArtifactDefinition> toscaArtifacts = new HashMap<>(); + + Set<Entry<String, ArtifactDefinition>> specificet = new HashSet<>(); + + for (Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + ArtifactDefinition artifact = entry.getValue(); + ArtifactGroupTypeEnum artifactGroupType = artifact.getArtifactGroupType(); + if (artifactGroupType == null) { + artifactGroupType = ArtifactGroupTypeEnum.INFORMATIONAL; + } + + switch (artifactGroupType) { + case DEPLOYMENT: + deploymentArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + case SERVICE_API: + serviceApiArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + case TOSCA: + toscaArtifacts.put(artifact.getArtifactLabel(), artifact); + specificet.add(entry); + break; + default: + break; + } + + } + artifacts.entrySet().removeAll(specificet); + + component.setSpecificComponetTypeArtifacts(serviceApiArtifacts); + component.setDeploymentArtifacts(deploymentArtifacts); + component.setToscaArtifacts(toscaArtifacts); + component.setArtifacts(artifacts); + } + return component; + } + + private <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> collectComponents(TitanGraph graph, NodeTypeEnum neededType, String categoryUid, NodeTypeEnum categoryType, Class<S> clazz) { + List<T> components = new ArrayList<>(); + Either<List<ImmutablePair<S, GraphEdge>>, TitanOperationStatus> parentNodes = titanGenericDao.getParentNodes(UniqueIdBuilder.getKeyByNodeType(categoryType), categoryUid, GraphEdgeLabels.CATEGORY, neededType, clazz); + if (parentNodes.isLeft()) { + for (ImmutablePair<S, GraphEdge> component : parentNodes.left().value()) { + ComponentMetadataDataDefinition componentData = component.getLeft().getMetadataDataDefinition(); + Boolean isHighest = componentData.isHighestVersion(); + Boolean isComplex = neededType == NodeTypeEnum.Resource ? ResourceTypeEnum.VF.equals(((ResourceMetadataDataDefinition) componentData).getResourceType()) : true; + if (isHighest && isComplex) { + Either<T, StorageOperationStatus> result = getLightComponent(componentData.getUniqueId(), true); + if (result.isRight()) { + return Either.right(result.right().value()); + } + components.add(result.left().value()); + } + } + } + return Either.left(components); + } + + protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryUid(String categoryUid, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction, + Class<S> clazz) { + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + + } + return collectComponents(graph.left().value(), neededType, categoryUid, categoryType, clazz); + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + protected <T, S extends ComponentMetadataData> Either<List<T>, StorageOperationStatus> fetchByCategoryOrSubCategoryName(String categoryName, NodeTypeEnum categoryType, String categoryLabel, NodeTypeEnum neededType, boolean inTransaction, + Class<S> clazz) { + List<T> components = new ArrayList<>(); + try { + Class categoryClazz = categoryType == NodeTypeEnum.ServiceNewCategory ? CategoryData.class : SubCategoryData.class; + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), categoryName); + Either<List<GraphNode>, TitanOperationStatus> getCategory = titanGenericDao.getByCriteria(categoryType, props, categoryClazz); + if (getCategory.isRight()) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + + } + for (GraphNode category : getCategory.left().value()) { + Either<List<T>, StorageOperationStatus> result = collectComponents(graph.left().value(), neededType, (String) category.getUniqueId(), categoryType, clazz); + if (result.isRight()) { + return result; + } + components.addAll(result.left().value()); + } + + return Either.left(components); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, boolean inTransaction, NodeTypeEnum neededType) { + return null; + } + + protected Either<List<Component>, StorageOperationStatus> getFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction, TitanGenericDao titanGenericDao, + NodeTypeEnum neededType) { + + Either<List<Component>, StorageOperationStatus> result = null; + + try { + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graph.right().value())); + return result; + } + Iterable<TitanVertex> users; + + if (userId == null) { + // get all users by label + // for Tester and Admin retrieve all users + + // users = + // graph.left().value().getVertices(GraphPropertiesDictionary.LABEL.getProperty(), + // NodeTypeEnum.User.getName()); + users = graph.left().value().query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.User.getName()).vertices(); + + } else { + // for Designer retrieve specific user + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User); + // users = graph.left().value().getVertices(key, userId); + users = graph.left().value().query().has(key, userId).vertices(); + } + Iterator<TitanVertex> userIterator = users.iterator(); + + List<Component> components = new ArrayList<>(); + while (userIterator.hasNext()) { + Vertex vertexUser = userIterator.next(); + + // get all resource with current state + Iterator<Edge> iterator = vertexUser.edges(Direction.OUT, GraphEdgeLabels.STATE.getProperty()); + + List<Component> componentsPerUser = fetchComponents(lifecycleStates, iterator, neededType, inTransaction); + + HashSet<String> ids = new HashSet<String>(); + + if (componentsPerUser != null) { + for (Component comp : componentsPerUser) { + ids.add(comp.getUniqueId()); + components.add(comp); + } + } + + if (lastStateStates != null && !lastStateStates.isEmpty()) { + // get all resource with last state + iterator = vertexUser.edges(Direction.OUT, GraphEdgeLabels.LAST_STATE.getProperty()); + boolean isFirst; + componentsPerUser = fetchComponents(lastStateStates, iterator, neededType, inTransaction); + if (componentsPerUser != null) { + for (Component comp : componentsPerUser) { + isFirst = true; + + if (ids.contains(comp.getUniqueId())) { + isFirst = false; + } + if (isFirst == true) { + components.add(comp); + } + + } + } + } + + } // whlile users + + result = Either.left(components); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + + } + + private List<Component> fetchComponents(Set<LifecycleStateEnum> lifecycleStates, Iterator<Edge> iterator, NodeTypeEnum neededType, boolean inTransaction) { + List<Component> components = new ArrayList<>(); + while (iterator.hasNext()) { + Edge edge = iterator.next(); + + String stateStr = edge.value(GraphEdgePropertiesDictionary.STATE.getProperty()); + LifecycleStateEnum state = LifecycleStateEnum.findState(stateStr); + if (state == null) { + log.debug("not supported STATE for element {}", stateStr); + continue; + } + if (lifecycleStates != null && lifecycleStates.contains(state)) { + Vertex vertexComponent = edge.inVertex(); + + Boolean isHighest = vertexComponent.value(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty()); + if (isHighest) { + + String nodeTypeStr = vertexComponent.value(GraphPropertiesDictionary.LABEL.getProperty()); + // get only latest versions + NodeTypeEnum nodeType = NodeTypeEnum.getByName(nodeTypeStr); + + if (nodeType == null) { + log.debug("missing node label for vertex {}", vertexComponent); + continue; + } + + if (neededType.equals(nodeType)) { + switch (nodeType) { + case Service: + handleNode(components, vertexComponent, nodeType, inTransaction); + break; + case Resource: + Boolean isAbtract = vertexComponent.value(GraphPropertiesDictionary.IS_ABSTRACT.getProperty()); + if (false == isAbtract) { + handleNode(components, vertexComponent, nodeType, inTransaction); + } // if not abstract + break; + case Product: + handleNode(components, vertexComponent, nodeType, inTransaction); + break; + default: + log.debug("not supported node type {}", nodeType); + break; + }// case + } // needed type + } + } // if + } // while resources + return components; + } + + protected <T> void handleNode(List<T> components, Vertex vertexComponent, NodeTypeEnum nodeType, boolean inTransaction) { + String id; + + id = vertexComponent.value(UniqueIdBuilder.getKeyByNodeType(nodeType)); + if (id != null) { + Either<T, StorageOperationStatus> component = getLightComponent(id, inTransaction); + if (component.isRight()) { + log.debug("Failed to get component for id = {} error: {} skip resource", id, component.right().value()); + } else { + components.add(component.left().value()); + } + } else { + + Map<String, Object> properties = this.titanGenericDao.getProperties(vertexComponent); + log.debug("missing resource unique id for node with properties {}", properties); + } + } + + /** + * + * @param component + * @param inTransaction + * @param titanGenericDao + * @param clazz + * @return + */ + public <T> Either<T, StorageOperationStatus> updateComponent(Component component, boolean inTransaction, TitanGenericDao titanGenericDao, Class<T> clazz, NodeTypeEnum type) { + + ComponentParametersView componentParametersView = new ComponentParametersView(); + return updateComponentFilterResult(component, inTransaction, titanGenericDao, clazz, type, componentParametersView); + + } + + private Either<ArtifactData, StorageOperationStatus> generateAndUpdateToscaFileName(String componentType, String componentName, String componentId, NodeTypeEnum type, ArtifactDefinition artifactInfo) { + Map<String, Object> getConfig = (Map<String, Object>) ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts().entrySet().stream().filter(p -> p.getKey().equalsIgnoreCase(artifactInfo.getArtifactLabel())) + .findAny().get().getValue(); + artifactInfo.setArtifactName(componentType + "-" + componentName + getConfig.get("artifactName")); + return artifactOperation.updateToscaArtifactNameOnGraph(artifactInfo, artifactInfo.getUniqueId(), type, componentId); + } + + protected StorageOperationStatus moveCategoryEdge(Component component, ComponentMetadataData componentData, CategoryDefinition newCategory, NodeTypeEnum type) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation categoryRelation = new GraphRelation(); + categoryRelation.setType(GraphEdgeLabels.CATEGORY.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(type, UniqueIdBuilder.getKeyByNodeType(type), component.getUniqueId()); + categoryRelation.setFrom(relationEndPoint); + Either<GraphRelation, TitanOperationStatus> deleteOutgoingRelation = titanGenericDao.deleteOutgoingRelation(categoryRelation); + if (deleteOutgoingRelation.isRight()) { + log.error("Failed to delete category from component {}. Edge type is {}", componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteOutgoingRelation.right().value()); + return result; + } + + log.debug("After removing edge from graph {}", deleteOutgoingRelation); + + NodeTypeEnum categoryType; + if (NodeTypeEnum.Service.name().equalsIgnoreCase(type.name())) { + categoryType = NodeTypeEnum.ServiceCategory; + } else { + categoryType = NodeTypeEnum.ResourceCategory; + } + Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation.getNewCategoryData(newCategory.getName(), NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + log.error("Cannot find category " + newCategory.getName() + " in the graph. status is " + status); + return status; + } + + CategoryData categoryData = categoryResult.left().value(); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(componentData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating category {} to component {}. Edge type is {}", categoryData, componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + if (createRelation.isRight()) { + log.error("Failed to associate category {} to component {}. Edge type is {}", categoryData, componentData.getUniqueId(), GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + + return result; + } + + private StorageOperationStatus moveLastModifierEdge(Component component, ComponentMetadataData componentData, UserData modifierUserData, NodeTypeEnum type) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation lastModifierRelation = new GraphRelation(); + lastModifierRelation.setType(GraphEdgeLabels.LAST_MODIFIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(type, UniqueIdBuilder.getKeyByNodeType(type), component.getUniqueId()); + lastModifierRelation.setTo(relationEndPoint); + Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation = titanGenericDao.deleteIncomingRelation(lastModifierRelation); + if (deleteIncomingRelation.isRight()) { + log.error("Failed to delete user from component {}. Edge type is {}", componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return result; + } + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(modifierUserData, componentData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to component {}. Edge type is {}", modifierUserData, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (createRelation.isRight()) { + log.error("Failed to associate user {} to component {}. Edge type is {}", modifierUserData, componentData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + return result; + } + + protected abstract ComponentMetadataData getMetaDataFromComponent(Component component); + + public abstract <T> Either<T, StorageOperationStatus> getComponent(String id, boolean inTransaction); + + public abstract <T> Either<T, StorageOperationStatus> getComponent(String id, ComponentParametersView componentParametersView, boolean inTrasnaction); + + // public abstract <T> Either<T, StorageOperationStatus> + // getComponent_tx(String id, boolean inTransaction); + + protected abstract <T> Either<T, StorageOperationStatus> getComponentByNameAndVersion(String name, String version, Map<String, Object> additionalParams, boolean inTransaction); + + public abstract <T> Either<T, StorageOperationStatus> getLightComponent(String id, boolean inTransaction); + + public abstract <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, boolean inTransaction); + + abstract Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData); + + abstract TitanOperationStatus setComponentCategoriesFromGraph(Component component); + + protected abstract Either<Component, StorageOperationStatus> getMetadataComponent(String id, boolean inTransaction); + + protected abstract <T> Either<T, StorageOperationStatus> updateComponent(T component, boolean inTransaction); + + protected abstract <T> Either<T, StorageOperationStatus> updateComponentFilterResult(T component, boolean inTransaction, ComponentParametersView filterParametersView); + + public abstract Either<Component, StorageOperationStatus> deleteComponent(String id, boolean inTransaction); + + public <T> Either<T, StorageOperationStatus> cloneComponent(T other, String version, boolean inTransaction) { + return cloneComponent(other, version, null, inTransaction); + } + + public abstract <T> Either<T, StorageOperationStatus> cloneComponent(T other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction); + + public abstract Component getDefaultComponent(); + + public abstract boolean isComponentExist(String componentId); + + public abstract Either<Boolean, StorageOperationStatus> validateComponentNameExists(String componentName); + + public abstract Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId); + + protected Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId, NodeTypeEnum nodeType) { + + Either<GraphRelation, TitanOperationStatus> relationByCriteria = titanGenericDao.getIncomingRelationByCriteria(new UniqueIdData(nodeType, componentId), GraphEdgeLabels.INSTANCE_OF, null); + if (relationByCriteria.isRight() && !relationByCriteria.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("failed to check relations for component node. id = {}, type = {}, error = {}", componentId, nodeType, relationByCriteria.right().value().name()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(relationByCriteria.right().value())); + } + + if (relationByCriteria.isLeft()) { + // component is in use + return Either.left(true); + } else { + return Either.left(false); + } + + } + + public abstract Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(); + + protected Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion(NodeTypeEnum nodeType) { + + List<String> componentIdsToDelete = new ArrayList<String>(); + // get all components marked for delete + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + + Either<List<ComponentMetadataData>, TitanOperationStatus> componentsToDelete = titanGenericDao.getByCriteria(nodeType, props, ComponentMetadataData.class); + + if (componentsToDelete.isRight()) { + TitanOperationStatus error = componentsToDelete.right().value(); + if (error.equals(TitanOperationStatus.NOT_FOUND)) { + log.trace("no components to delete"); + return Either.left(componentIdsToDelete); + } else { + log.info("failed to find components to delete. error : {}", error.name()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error)); + } + + } + for (ComponentMetadataData resourceData : componentsToDelete.left().value()) { + componentIdsToDelete.add(resourceData.getMetadataDataDefinition().getUniqueId()); + } + return Either.left(componentIdsToDelete); + } + + protected <T extends GraphNode> Either<List<T>, TitanOperationStatus> __getLastVersion(NodeTypeEnum type, Map<String, Object> props, Class<T> clazz) { + try { + + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + return Either.right(graph.right().value()); + } + + TitanGraph tGraph = graph.left().value(); + TitanGraphQuery<? extends TitanGraphQuery> query = tGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), type.getName()); + + if (props != null && !props.isEmpty()) { + for (Map.Entry<String, Object> entry : props.entrySet()) { + query = query.hasNot(entry.getKey(), entry.getValue()); + } + } + query.has(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Iterable<TitanVertex> vertices = query.vertices(); + + if (vertices == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Iterator<TitanVertex> iterator = vertices.iterator(); + List<T> result = new ArrayList<T>(); + + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + + Map<String, Object> newProp = titanGenericDao.getProperties(vertex); + T element = GraphElementFactory.createElement(type.getName(), GraphElementTypeEnum.Node, newProp, clazz); + result.add(element); + } + if (result.size() == 0) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + log.debug("No nodes in graph for criteria : from type = {} and properties = {}", type, props); + return Either.left(result); + } catch (Exception e) { + log.debug("Failed get by criteria for type = {} and properties = {}. {}", type, props, e); + return Either.right(TitanGraphClient.handleTitanException(e)); + } + } + + protected <T extends GraphNode> Either<List<T>, TitanOperationStatus> getLastVersion(NodeTypeEnum type, Map<String, Object> hasNotProps, Class<T> clazz) { + return getLastVersion(type, null, hasNotProps, clazz); + } + + protected <T extends GraphNode> Either<List<T>, TitanOperationStatus> getLastVersion(NodeTypeEnum type, Map<String, Object> hasProps, Map<String, Object> hasNotProps, Class<T> clazz) { + + Map<String, Object> props = new HashMap<>(); + + if (hasProps != null) { + props.putAll(hasProps); + } + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either<List<T>, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + return byCriteria; + + } + + public <T, S extends GraphNode> Either<Set<T>, StorageOperationStatus> getComponentCatalogData(NodeTypeEnum type, Map<String, Object> propertiesToMatch, Class<T> clazz1, Class<S> clazz2, boolean inTransaction) { + log.debug("Start getComponentCatalogData for type: {}", type.name()); + Set<T> result = new HashSet<T>(); + Either<List<S>, TitanOperationStatus> lastVersionNodes = getLastVersion(type, propertiesToMatch, clazz2); + Either<Set<T>, StorageOperationStatus> last = retrieveComponentsFromNodes(lastVersionNodes, inTransaction); + if (last.isLeft() && last.left().value() != null) { + result.addAll(last.left().value()); + } + if (type == NodeTypeEnum.Resource) { + propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), false); + } + Either<List<S>, TitanOperationStatus> componentsNodes = titanGenericDao.getByCriteria(type, propertiesToMatch, clazz2); + Either<Set<T>, StorageOperationStatus> certified = retrieveComponentsFromNodes(componentsNodes, inTransaction); + if (certified.isLeft() && certified.left().value() != null) { + result.addAll(certified.left().value()); + } + return Either.left(result); + + } + + protected <T, S extends GraphNode> Either<Set<T>, StorageOperationStatus> retrieveComponentsFromNodes(Either<List<S>, TitanOperationStatus> componentsNodes, boolean inTransaction) { + Set<T> result = new HashSet<T>(); + if (componentsNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty list + if (componentsNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("No components were found"); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentsNodes.right().value())); + } + } else { + List<S> componentDataList = componentsNodes.left().value(); + for (S componentData : componentDataList) { + // Either<T, StorageOperationStatus> component = + // getComponent((String) componentData.getUniqueId(), + // inTransaction); + Either<T, StorageOperationStatus> component = getLightComponent((String) componentData.getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get component for id = {} error : {} skip resource", componentData.getUniqueId(), component.right().value()); + // return Either.right(service.right().value()); + } else { + result.add(component.left().value()); + } + } + } + return Either.left(result); + } + + protected StorageOperationStatus removeArtifactsFromComponent(Component component, NodeTypeEnum componentType) { + + String componentId = component.getUniqueId(); + // Map<String, ArtifactDefinition> artifacts = component.getArtifacts(); + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsRes = artifactOperation.getArtifacts(componentId, componentType, true); + if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return artifactsRes.right().value(); + } + if (artifactsRes.isLeft() && artifactsRes.left().value() != null) { + Map<String, ArtifactDefinition> artifacts = artifactsRes.left().value(); + for (Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource = artifactOperation.removeArifactFromResource(componentId, artifactDefinition.getUniqueId(), componentType, true, true); + if (removeArifactFromResource.isRight()) { + return removeArifactFromResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + } + + public Either<List<Component>, StorageOperationStatus> getTesterFollowedComponent(String userId, Set<LifecycleStateEnum> lifecycleStates, boolean inTransaction, NodeTypeEnum neededType) { + List<Component> resList = new ArrayList<>(); + Either<List<Component>, StorageOperationStatus> rip = getFollowedComponent(userId, lifecycleStates, null, inTransaction, titanGenericDao, neededType); + if (rip.isLeft()) { + List<Component> ripRes = rip.left().value(); + if (ripRes != null && !ripRes.isEmpty()) { + resList.addAll(ripRes); + } + Set<LifecycleStateEnum> rfcState = new HashSet<>(); + rfcState.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either<List<Component>, StorageOperationStatus> rfc = getFollowedComponent(null, rfcState, null, inTransaction, titanGenericDao, neededType); + if (rfc.isLeft()) { + List<Component> rfcRes = rfc.left().value(); + if (rfcRes != null && !rfcRes.isEmpty()) { + resList.addAll(rfcRes); + } + } else { + return Either.right(rfc.right().value()); + } + + } else { + return Either.right(rip.right().value()); + } + return Either.left(resList); + + } + + /** + * generate UUID only for case that version is "XX.01" - (start new version) + * + * @param component + */ + protected void generateUUID(Component component) { + String version = component.getVersion(); + if (uuidNewVersion.matcher(version).matches()) { + UUID uuid = UUID.randomUUID(); + component.getComponentMetadataDefinition().getMetadataDataDefinition().setUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + } + } + + protected <T extends GraphNode> Either<Map<String, String>, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, Component component, Class<T> clazz) { + return getVersionList(type, version, component.getUUID(), component.getSystemName(), clazz); + } + + protected <T extends GraphNode> Either<Map<String, String>, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, String uuid, String systemName, Class<T> clazz) { + Map<String, Object> props = new HashMap<String, Object>(); + Map<String, Object> hasNotProps = new HashMap<String, Object>(); + + if (version.startsWith("0")) { + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + } else { + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + } + hasNotProps.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + Either<List<T>, TitanOperationStatus> result = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + Map<String, String> versionMap = new HashMap<String, String>(); + if (result.isRight()) { + if (!result.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(result.right().value()); + } + + } else { + switch (type) { + case Resource: + List<ResourceMetadataData> components = (List<ResourceMetadataData>) result.left().value(); + for (ResourceMetadataData data : components) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + break; + case Service: + List<ServiceMetadataData> componentsS = (List<ServiceMetadataData>) result.left().value(); + for (ServiceMetadataData data : componentsS) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + break; + case Product: + List<ProductMetadataData> componentsP = (List<ProductMetadataData>) result.left().value(); + for (ProductMetadataData data : componentsP) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + default: + break; + } + } + + return Either.left(versionMap); + } + + protected StorageOperationStatus deleteAdditionalInformation(NodeTypeEnum nodeType, String componentId) { + + Either<AdditionalInformationDefinition, StorageOperationStatus> deleteRes = additionalInformationOperation.deleteAllAdditionalInformationParameters(nodeType, componentId, true); + + if (deleteRes.isRight()) { + StorageOperationStatus status = deleteRes.right().value(); + return status; + } + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus addAdditionalInformation(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition informationDefinition) { + + Either<AdditionalInformationDefinition, TitanOperationStatus> status = additionalInformationOperation.addAdditionalInformationNode(nodeType, componentId, informationDefinition); + + if (status.isRight()) { + TitanOperationStatus titanStatus = status.right().value(); + return DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + + log.trace("After adding additional information to component {}. Result is {}", componentId, status.left().value()); + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus addAdditionalInformation(NodeTypeEnum nodeType, String componentId, AdditionalInformationDefinition informationDefinition, TitanVertex metadataVertex) { + + TitanOperationStatus status = additionalInformationOperation.addAdditionalInformationNode(nodeType, componentId, informationDefinition, metadataVertex); + log.trace("After adding additional information to component {}. Result is {}", componentId, status); + + if (!status.equals(TitanOperationStatus.OK)) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + return StorageOperationStatus.OK; + + } + + public Either<List<ArtifactDefinition>, StorageOperationStatus> getComponentArtifactsForDelete(String parentId, NodeTypeEnum parentType, boolean inTransacton) { + List<ArtifactDefinition> artifacts = new ArrayList<ArtifactDefinition>(); + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsResponse = artifactOperation.getArtifacts(parentId, parentType, inTransacton); + if (artifactsResponse.isRight()) { + if (!artifactsResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + log.debug("failed to retrieve artifacts for {} {}", parentType, parentId); + return Either.right(artifactsResponse.right().value()); + } + } else { + artifacts.addAll(artifactsResponse.left().value().values()); + } + + if (NodeTypeEnum.Resource.equals(parentType)) { + Either<List<ArtifactDefinition>, StorageOperationStatus> interfacesArtifactsForResource = getAdditionalArtifacts(parentId, false, true); + if (artifactsResponse.isRight() && !interfacesArtifactsForResource.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + log.debug("failed to retrieve interface artifacts for {} {}", parentType, parentId); + return Either.right(interfacesArtifactsForResource.right().value()); + } else if (artifactsResponse.isLeft()) { + artifacts.addAll(interfacesArtifactsForResource.left().value()); + } + } + return Either.left(artifacts); + } + + protected void addComponentInternalFields(ComponentMetadataData componentMetadataData) { + org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition metadataDataDefinition = componentMetadataData.getMetadataDataDefinition(); + Long creationDate = metadataDataDefinition.getCreationDate(); + + long currentDate = System.currentTimeMillis(); + if (creationDate == null) { + metadataDataDefinition.setCreationDate(currentDate); + } + metadataDataDefinition.setLastUpdateDate(currentDate); + + String lifecycleStateEnum = metadataDataDefinition.getState(); + if (lifecycleStateEnum == null) { + metadataDataDefinition.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + } + String componentUniqueId = UniqueIdBuilder.buildComponentUniqueId(); + metadataDataDefinition.setUniqueId(componentUniqueId); + metadataDataDefinition.setHighestVersion(true); + } + + protected StorageOperationStatus createTagsForComponent(Component component) { + List<String> tags = component.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either<List<TagData>, StorageOperationStatus> tagsResult = createNewTagsList(tags); + + if (tagsResult == null) { + log.debug("tagsResult is null"); + return StorageOperationStatus.GENERAL_ERROR; + } + if (tagsResult.isRight()) { + return tagsResult.right().value(); + } + List<TagData> tagsToCreate = tagsResult.left().value(); + return createTagNodesOnGraph(tagsToCreate); + } + log.trace("All tags created succesfully for component {}", component.getUniqueId()); + return StorageOperationStatus.OK; + } + + protected Either<List<GroupingData>, StorageOperationStatus> findGroupingsForComponent(NodeTypeEnum nodeTypeEnum, Component component) { + List<CategoryDefinition> categories = component.getCategories(); + List<GroupingData> groupingDataToAssociate = new ArrayList<>(); + if (categories != null) { + groupingDataToAssociate = new ArrayList<>(); + for (CategoryDefinition categoryDefinition : categories) { + List<SubCategoryDefinition> subcategories = categoryDefinition.getSubcategories(); + if (subcategories != null) { + for (SubCategoryDefinition subCategoryDefinition : subcategories) { + List<GroupingDefinition> groupingDataDefinitions = subCategoryDefinition.getGroupings(); + if (groupingDataDefinitions != null) { + for (GroupingDataDefinition grouping : groupingDataDefinitions) { + String groupingId = grouping.getUniqueId(); + Either<GroupingData, TitanOperationStatus> findGroupingEither = findGrouping(nodeTypeEnum, groupingId); + if (findGroupingEither.isRight()) { + TitanOperationStatus status = findGroupingEither.right().value(); + log.error("Cannot find grouping {} in the graph. status is {}", groupingId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + groupingDataToAssociate.add(findGroupingEither.left().value()); + } + } + } + } + } + } + } + return Either.left(groupingDataToAssociate); + } + + protected TitanOperationStatus associateGroupingsToComponent(ComponentMetadataData componentMetadataData, List<GroupingData> groupingDataToAssociate) { + for (GroupingData groupingData : groupingDataToAssociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.GROUPING; + Either<GraphRelation, TitanOperationStatus> result = titanGenericDao.createRelation(componentMetadataData, groupingData, groupingLabel, null); + log.debug("After associating grouping {} to component {}. Edge type is {}", groupingData, componentMetadataData, groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings associated succesfully to component {}", componentMetadataData); + return TitanOperationStatus.OK; + } + + public abstract Either<Integer, StorageOperationStatus> increaseAndGetComponentInstanceCounter(String componentId, boolean inTransaction); + + protected Either<Integer, StorageOperationStatus> increaseAndGetComponentInstanceCounter(String componentId, NodeTypeEnum nodeType, boolean inTransaction) { + Either<Integer, StorageOperationStatus> result = null; + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata, nodeType:{} , id: {}", nodeType, componentId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + Integer instanceCounter = vertex.value(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty()); + ++instanceCounter; + vertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty(), instanceCounter); + result = Either.left(instanceCounter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("increaseAndGetComponentInstanceCounter operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("increaseAndGetComponentInstanceCounter operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + protected Either<Integer, StorageOperationStatus> setComponentInstanceCounter(String componentId, NodeTypeEnum nodeType, int counter, boolean inTransaction) { + Either<Integer, StorageOperationStatus> result = null; + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata ofor id = {}", componentId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + vertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty(), counter); + result = Either.left(counter); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("deleteService operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteService operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + protected TitanOperationStatus setComponentInstancesFromGraph(String uniqueId, Component component, NodeTypeEnum containerNodeType, NodeTypeEnum compInstNodeType) { + + Either<ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>>, TitanOperationStatus> resourceInstancesOfService = componentInstanceOperation.getComponentInstancesOfComponent(uniqueId, containerNodeType, compInstNodeType); + + if (resourceInstancesOfService.isRight()) { + TitanOperationStatus status = resourceInstancesOfService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } else { + log.error("Failed to fetch resource instances and their relations. status is {}", status); + } + return status; + } + + ImmutablePair<List<ComponentInstance>, List<RequirementCapabilityRelDef>> immutablePair = resourceInstancesOfService.left().value(); + List<ComponentInstance> instances = immutablePair.getKey(); + List<RequirementCapabilityRelDef> relations = immutablePair.getValue(); + + component.setComponentInstances(instances); + component.setComponentInstancesRelations(relations); + + return TitanOperationStatus.OK; + } + + /** + * set all properties of all of its resources + * + * @param uniqueId + * @return + */ + protected TitanOperationStatus ___setComponentInstancesPropertiesFromGraph(String uniqueId, Component component) { + + List<ComponentInstance> resourceInstances = component.getComponentInstances(); + + Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties = new HashMap<>(); + + Map<String, List<PropertyDefinition>> alreadyProcessedResources = new HashMap<>(); + + if (resourceInstances != null) { + for (ComponentInstance resourceInstance : resourceInstances) { + + log.debug("Going to update properties of resource instance {}", resourceInstance.getUniqueId()); + String resourceUid = resourceInstance.getComponentUid(); + + List<PropertyDefinition> properties = alreadyProcessedResources.get(resourceUid); + if (properties == null) { + properties = new ArrayList<>(); + TitanOperationStatus findAllRes = propertyOperation.findAllResourcePropertiesRecursively(resourceUid, properties); + if (findAllRes != TitanOperationStatus.OK) { + return findAllRes; + } + alreadyProcessedResources.put(resourceUid, properties); + } + log.debug("After getting properties of resource {}. Number of properties is {}", resourceUid, (properties == null ? 0 : properties.size())); + if (false == properties.isEmpty()) { + + String resourceInstanceUid = resourceInstance.getUniqueId(); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesRes = propertyOperation.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid); + log.debug("After fetching property under resource instance {}", resourceInstanceUid); + if (propertyValuesRes.isRight()) { + TitanOperationStatus status = propertyValuesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } + + Map<String, ComponentInstanceProperty> propertyIdToValue = new HashMap<>(); + populateMapperWithPropertyValues(propertyValuesRes, propertyIdToValue); + + List<ComponentInstanceProperty> resourceInstancePropertyList = new ArrayList<>(); + for (PropertyDefinition propertyDefinition : properties) { + + String defaultValue = propertyDefinition.getDefaultValue(); + String value = defaultValue; + String valueUid = null; + + String propertyId = propertyDefinition.getUniqueId(); + ComponentInstanceProperty valuedProperty = propertyIdToValue.get(propertyId); + if (valuedProperty != null) { + String newValue = valuedProperty.getValue(); + // if (newValue != null) { + value = newValue; + // } + + valueUid = valuedProperty.getValueUniqueUid(); + log.trace("Found value {} under resource instance whice override the default value {}", value, defaultValue); + } + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(propertyDefinition, value, valueUid); + + // TODO: currently ignore constraints since they are not + // inuse and cause to error in convertion to object. + resourceInstanceProperty.setConstraints(null); + + resourceInstancePropertyList.add(resourceInstanceProperty); + + } + + resourceInstancesProperties.put(resourceInstanceUid, resourceInstancePropertyList); + } + + } + + component.setComponentInstancesProperties(resourceInstancesProperties); + } + + return TitanOperationStatus.OK; + } + + private void populateMapperWithPropertyValues(Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesRes, Map<String, ComponentInstanceProperty> propertyIdToValue) { + + if (propertyValuesRes.isLeft()) { + List<ComponentInstanceProperty> resourceInstanceValues = propertyValuesRes.left().value(); + if (resourceInstanceValues != null) { + for (ComponentInstanceProperty resourceInstanceProperty : resourceInstanceValues) { + propertyIdToValue.put(resourceInstanceProperty.getUniqueId(), resourceInstanceProperty); + } + } + } + } + + public abstract Either<List<ArtifactDefinition>, StorageOperationStatus> getAdditionalArtifacts(String resourceId, boolean recursively, boolean inTransaction); + + protected abstract StorageOperationStatus validateCategories(Component currentComponent, Component component, ComponentMetadataData componentData, NodeTypeEnum type); + + protected abstract <T extends Component> StorageOperationStatus updateDerived(Component component, Component currentComponent, ComponentMetadataData updatedResourceData, Class<T> clazz); + + public abstract Either<Component, StorageOperationStatus> markComponentToDelete(Component componentToDelete, boolean inTransaction); + + protected Either<Component, StorageOperationStatus> internalMarkComponentToDelete(Component componentToDelete, boolean inTransaction) { + Either<Component, StorageOperationStatus> result = null; + + if ((componentToDelete.getIsDeleted() != null) && componentToDelete.getIsDeleted() && !componentToDelete.isHighestVersion()) { + // component already marked for delete + result = Either.left(componentToDelete); + return result; + } else { + + ComponentMetadataData componentMetaData = getMetaDataFromComponent(componentToDelete); + + componentMetaData.getMetadataDataDefinition().setIsDeleted(true); + componentMetaData.getMetadataDataDefinition().setHighestVersion(false); + componentMetaData.getMetadataDataDefinition().setLastUpdateDate(System.currentTimeMillis()); + try { + Either<ComponentMetadataData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(componentMetaData, ComponentMetadataData.class); + + StorageOperationStatus updateComponent; + if (updateNode.isRight()) { + log.debug("Failed to update component {}. Status is {}", componentMetaData.getUniqueId(), updateNode.right().value()); + updateComponent = DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()); + result = Either.right(updateComponent); + return result; + } + + result = Either.left(componentToDelete); + return result; + } finally { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("updateResource operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("updateResource operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + } + + private Either<List<RequirementDefinition>, TitanOperationStatus> convertReqDataListToReqDefList(ComponentInstance componentInstance, List<ImmutablePair<RequirementData, GraphEdge>> requirementData) { + ConvertDataToDef<RequirementDefinition, RequirementData> convertor = (data, edge) -> convertReqDataToReqDef(data, edge); + AddOwnerData<RequirementDefinition> dataAdder = (reqDef, compInstance) -> addOwnerDataReq(reqDef, compInstance); + + return convertDataToDefinition(componentInstance, requirementData, convertor, dataAdder); + } + + private Either<List<CapabilityDefinition>, TitanOperationStatus> convertCapDataListToCapDefList(ComponentInstance componentInstance, List<ImmutablePair<CapabilityData, GraphEdge>> capabilityData) { + ConvertDataToDef<CapabilityDefinition, CapabilityData> convertor = (data, edge) -> convertCapDataToCapDef(data, edge); + AddOwnerData<CapabilityDefinition> dataAdder = (capDef, compInstance) -> addOwnerDataCap(capDef, compInstance); + Either<List<CapabilityDefinition>, TitanOperationStatus> convertationResult = convertDataToDefinition(componentInstance, capabilityData, convertor, dataAdder); + if (convertationResult.isLeft()) { + convertationResult = componentInstanceOperation.updateCapDefPropertyValues(componentInstance, convertationResult.left().value()); + } + return convertationResult; + } + + private Either<CapabilityDefinition, TitanOperationStatus> convertCapDataToCapDef(CapabilityData data, GraphEdge edge) { + Either<CapabilityDefinition, TitanOperationStatus> eitherDef = capabilityOperation.getCapabilityByCapabilityData(data); + + if (eitherDef.isLeft()) { + CapabilityDefinition capDef = eitherDef.left().value(); + Map<String, Object> properties = edge.getProperties(); + if (properties != null) { + String name = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + String source = (String) properties.get(GraphEdgePropertiesDictionary.SOURCE.getProperty()); + List<String> sourcesList = new ArrayList<String>(); + capabilityOperation.getCapabilitySourcesList(source, sourcesList); + capDef.setName(name); + capDef.setCapabilitySources(sourcesList); + + String requiredOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + if (requiredOccurrences != null) { + capDef.setMinOccurrences(requiredOccurrences); + } + String leftOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null) { + capDef.setMaxOccurrences(leftOccurrences); + } + + } + eitherDef = Either.left(capDef); + } + return eitherDef; + } + + private Either<RequirementDefinition, TitanOperationStatus> convertReqDataToReqDef(RequirementData data, GraphEdge edge) { + Either<RequirementDefinition, TitanOperationStatus> eitherDef = requirementOperation.getRequirement(data.getUniqueId()); + + if (eitherDef.isLeft()) { + RequirementDefinition requirementDef = eitherDef.left().value(); + Map<String, Object> properties = edge.getProperties(); + if (properties != null) { + String name = (String) properties.get(GraphEdgePropertiesDictionary.NAME.getProperty()); + requirementDef.setName(name); + String requiredOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.REQUIRED_OCCURRENCES.getProperty()); + if (requiredOccurrences != null) { + requirementDef.setMinOccurrences(requiredOccurrences); + } + String leftOccurrences = (String) properties.get(GraphEdgePropertiesDictionary.LEFT_OCCURRENCES.getProperty()); + if (leftOccurrences != null) { + requirementDef.setMaxOccurrences(leftOccurrences); + } + } + eitherDef = Either.left(requirementDef); + } + return eitherDef; + } + + private <Def, Data> Either<List<Def>, TitanOperationStatus> convertDataToDefinition(ComponentInstance componentInstance, List<ImmutablePair<Data, GraphEdge>> requirementData, ConvertDataToDef<Def, Data> convertor, AddOwnerData<Def> dataAdder) { + Either<List<Def>, TitanOperationStatus> eitherResult; + // Convert Data To Definition + Stream<Either<Def, TitanOperationStatus>> reqDefStream = requirementData.stream().map(e -> convertor.convert(e.left, e.right)); + + // Collect But Stop After First Error + List<Either<Def, TitanOperationStatus>> filteredReqDefList = StreamUtils.takeWhilePlusOne(reqDefStream, p -> p.isLeft()).collect(Collectors.toList()); + Optional<Either<Def, TitanOperationStatus>> optionalError = filteredReqDefList.stream().filter(p -> p.isRight()).findAny(); + if (optionalError.isPresent()) { + eitherResult = Either.right(optionalError.get().right().value()); + } else { + // Convert From Either To Definition And Collect + List<Def> reqDefList = filteredReqDefList.stream().map(e -> e.left().value()).collect(Collectors.toList()); + // Add Owner Data + reqDefList.forEach(e -> dataAdder.addData(e, componentInstance)); + eitherResult = Either.left(reqDefList); + } + + return eitherResult; + } + + interface ConvertDataToDef<Def, Data> { + Either<Def, TitanOperationStatus> convert(Data d, GraphEdge edge); + } + + interface AddOwnerData<Def> { + void addData(Def def, ComponentInstance compInstance); + } + + private void addOwnerDataCap(CapabilityDefinition capDef, ComponentInstance componentInstance) { + capDef.setOwnerId(componentInstance.getUniqueId()); + capDef.setOwnerName(componentInstance.getName()); + } + + private void addOwnerDataReq(RequirementDefinition reqDef, ComponentInstance componentInstance) { + reqDef.setOwnerId(componentInstance.getUniqueId()); + reqDef.setOwnerName(componentInstance.getName()); + } + + public Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> getRequirements(Component component, NodeTypeEnum nodeTypeEnum, boolean inTransaction) { + final HashMap<String, List<RequirementDefinition>> emptyMap = new HashMap<>(); + Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherResult = Either.left(emptyMap); + try { + List<ComponentInstance> componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + Function<ComponentInstance, Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus>> dataCollector = e -> componentInstanceOperation.getRequirements(e, nodeTypeEnum); + Either<List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus>>>, TitanOperationStatus> eitherDataCollected = collectDataFromComponentsInstances(componentInstances, + dataCollector); + if (eitherDataCollected.isRight()) { + eitherResult = Either.right(eitherDataCollected.right().value()); + } else { + // Converts Data to Def stop if encountered conversion error + DataDefConvertor<RequirementDefinition, RequirementData> someConvertor = (e1, e2) -> convertReqDataListToReqDefList(e1, e2); + Either<List<List<RequirementDefinition>>, TitanOperationStatus> fullDefList = convertDataToDefComponentLevel(eitherDataCollected.left().value(), someConvertor); + if (fullDefList.isRight()) { + eitherResult = Either.right(fullDefList.right().value()); + } else { + Stream<RequirementDefinition> defStream = fullDefList.left().value().stream().flatMap(e -> e.stream()); + // Collect to Map and using grouping by + Map<String, List<RequirementDefinition>> capTypeCapListMap = defStream.collect(Collectors.groupingBy(e -> e.getCapability())); + eitherResult = Either.left(capTypeCapListMap); + } + + } + + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + return eitherResult; + } + + public Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> getCapabilities(Component component, NodeTypeEnum nodeTypeEnum, boolean inTransaction) { + final HashMap<String, List<CapabilityDefinition>> emptyMap = new HashMap<>(); + Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherResult = Either.left(emptyMap); + try { + List<ComponentInstance> componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + Function<ComponentInstance, Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus>> dataCollector = e -> componentInstanceOperation.getCapabilities(e, nodeTypeEnum); + Either<List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus>>>, TitanOperationStatus> eitherDataCollected = collectDataFromComponentsInstances(componentInstances, + dataCollector); + if (eitherDataCollected.isRight()) { + eitherResult = Either.right(eitherDataCollected.right().value()); + } else { + // Converts CapData to CapDef removes stop if encountered + // conversion error + DataDefConvertor<CapabilityDefinition, CapabilityData> someConvertor = (e1, e2) -> convertCapDataListToCapDefList(e1, e2); + Either<List<List<CapabilityDefinition>>, TitanOperationStatus> fullDefList = convertDataToDefComponentLevel(eitherDataCollected.left().value(), someConvertor); + if (fullDefList.isRight()) { + eitherResult = Either.right(fullDefList.right().value()); + } else { + Stream<CapabilityDefinition> defStream = fullDefList.left().value().stream().flatMap(e -> e.stream()); + // Collect to Map grouping by Type + Map<String, List<CapabilityDefinition>> capTypeCapListMap = defStream.collect(Collectors.groupingBy(e -> e.getType())); + eitherResult = Either.left(capTypeCapListMap); + } + + } + + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + return eitherResult; + } + + public <Data> Either<List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>>, TitanOperationStatus> collectDataFromComponentsInstances(List<ComponentInstance> componentInstances, + Function<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>> dataGetter) { + Either<List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>>, TitanOperationStatus> eitherResult; + + // Get List of Each componentInstance and it's Capabilities Data + Stream<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>> ownerDataStream = componentInstances.stream().map(element -> new ImmutablePair<>(element, dataGetter.apply(element))); + // Collect but stop after first error + List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>> ownerCapDataList = StreamUtils + .takeWhilePlusOne(ownerDataStream, p -> p.right.isLeft() || p.right.isRight() && p.right.right().value() == TitanOperationStatus.NOT_FOUND).collect(Collectors.toList()); + + Optional<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>> optionalError = ownerCapDataList.stream() + .filter(p -> p.right.isRight() && p.right.right().value() != TitanOperationStatus.NOT_FOUND).findAny(); + if (optionalError.isPresent()) { + eitherResult = Either.right(optionalError.get().right.right().value()); + } else { + eitherResult = Either.left(ownerCapDataList.stream().filter(p -> p.right.isLeft()).collect(Collectors.toList())); + } + + return eitherResult; + } + + interface DataDefConvertor<Def, Data> { + Either<List<Def>, TitanOperationStatus> convertDataToDefComponentInstance(ComponentInstance componentInstance, List<ImmutablePair<Data, GraphEdge>> data); + } + + public <Def, Data> Either<List<List<Def>>, TitanOperationStatus> convertDataToDefComponentLevel(List<ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>>> ownerCapDataList, + DataDefConvertor<Def, Data> convertor) { + // Converts CapData to CapDef removes stop if encountered conversion + // error + TitanOperationStatus error = null; + List<List<Def>> defList = new ArrayList<>(); + for (int i = 0; i < ownerCapDataList.size(); i++) { + ImmutablePair<ComponentInstance, Either<List<ImmutablePair<Data, GraphEdge>>, TitanOperationStatus>> immutablePair = ownerCapDataList.get(i); + Either<List<Def>, TitanOperationStatus> convertCapDataListToCapDefList = convertor.convertDataToDefComponentInstance(immutablePair.left, immutablePair.right.left().value()); + if (convertCapDataListToCapDefList.isRight()) { + error = convertCapDataListToCapDefList.right().value(); + break; + } else { + defList.add(convertCapDataListToCapDefList.left().value()); + } + + } + Either<List<List<Def>>, TitanOperationStatus> eitherResult = (error != null) ? Either.right(error) : Either.left(defList); + return eitherResult; + + } + + private Map<String, ComponentMetadataData> findLatestVersion(List<ComponentMetadataData> resourceDataList) { + Map<Pair<String, String>, ComponentMetadataData> latestVersionMap = new HashMap<Pair<String, String>, ComponentMetadataData>(); + for (ComponentMetadataData resourceData : resourceDataList) { + ComponentMetadataData latestVersionData = resourceData; + + ComponentMetadataDataDefinition metadataDataDefinition = resourceData.getMetadataDataDefinition(); + Pair<String, String> pair = createKeyPair(latestVersionData); + if (latestVersionMap.containsKey(pair)) { + latestVersionData = latestVersionMap.get(pair); + String currentVersion = latestVersionData.getMetadataDataDefinition().getVersion(); + String newVersion = metadataDataDefinition.getVersion(); + if (CommonBeUtils.compareAsdcComponentVersions(newVersion, currentVersion)) { + latestVersionData = resourceData; + } + } + if (log.isDebugEnabled()) + log.debug("last certified version of resource = {} version is {}", latestVersionData.getMetadataDataDefinition().getName(), latestVersionData.getMetadataDataDefinition().getVersion()); + + latestVersionMap.put(pair, latestVersionData); + } + + Map<String, ComponentMetadataData> resVersionMap = new HashMap<String, ComponentMetadataData>(); + for (ComponentMetadataData resourceData : latestVersionMap.values()) { + ComponentMetadataData latestVersionData = resourceData; + ComponentMetadataDataDefinition metadataDataDefinition = resourceData.getMetadataDataDefinition(); + if (resVersionMap.containsKey(metadataDataDefinition.getUUID())) { + latestVersionData = resVersionMap.get(metadataDataDefinition.getUUID()); + String currentVersion = latestVersionData.getMetadataDataDefinition().getVersion(); + String newVersion = metadataDataDefinition.getVersion(); + if (CommonBeUtils.compareAsdcComponentVersions(newVersion, currentVersion)) { + latestVersionData = resourceData; + } + } + if (log.isDebugEnabled()) + log.debug("last uuid version of resource = {} version is {}", latestVersionData.getMetadataDataDefinition().getName(), latestVersionData.getMetadataDataDefinition().getVersion()); + resVersionMap.put(latestVersionData.getMetadataDataDefinition().getUUID(), latestVersionData); + } + + return resVersionMap; + } + + private Pair<String, String> createKeyPair(ComponentMetadataData metadataData) { + Pair<String, String> pair = null; + NodeTypeEnum label = NodeTypeEnum.getByName(metadataData.getLabel()); + switch (label) { + case Resource: + pair = new ImmutablePair<String, String>(metadataData.getMetadataDataDefinition().getName(), ((ResourceMetadataDataDefinition) metadataData.getMetadataDataDefinition()).getResourceType().getValue()); + break; + default: + pair = new ImmutablePair<String, String>(metadataData.getMetadataDataDefinition().getName(), metadataData.getLabel()); + break; + } + + return pair; + } + + public Either<Collection<ComponentMetadataData>, StorageOperationStatus> getLatestVersionNotAbstractComponentsMetadataOnly(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType) { + try { + + // Map<String, Object> hasPpropertiesToMatch = new HashMap<>(); + // Map<String, Object> hasNotPpropertiesToMatch = new HashMap<>(); + List<ImmutableTriple<QueryType, String, Object>> properties = new ArrayList<>(); + if (componentTypeEnum.equals(ComponentTypeEnum.RESOURCE)) { + // hasPpropertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), + // isAbstract); + properties.add(new ImmutableTriple<>(QueryType.HAS, GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), isAbstract)); + + if (internalComponentType != null) { + switch (internalComponentType.toLowerCase()) { + case "vf": + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name())); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VF.name()); + break; + case "service": + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VFC.name())); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VFC.name()); + break; + case "vl": + properties.add(new ImmutableTriple<>(QueryType.HAS, GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VL.name())); + // hasPpropertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VL.name()); + break; + default: + break; + } + } + } + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())); + // hasNotPpropertiesToMatch.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), + // true); + properties.add(new ImmutableTriple<>(QueryType.HAS_NOT, GraphPropertiesDictionary.IS_DELETED.getProperty(), true)); + // Either<List<ComponentMetadataData>, TitanOperationStatus> + // resourceNodes = titanGenericDao.getByCriteria( + // componentTypeEnum.getNodeType(), hasPpropertiesToMatch, + // hasNotPpropertiesToMatch, + // ComponentMetadataData.class); + Either<List<ComponentMetadataData>, TitanOperationStatus> resourceNodes = titanGenericDao.getByCriteria(componentTypeEnum.getNodeType(), ComponentMetadataData.class, properties); + if (resourceNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty + // list + if (resourceNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList<>()); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceNodes.right().value())); + } + } else { + List<ComponentMetadataData> resourceDataList = resourceNodes.left().value(); + Collection<ComponentMetadataData> resCollection = resourceDataList; + if (isHighest != null && isHighest) { + Map<String, ComponentMetadataData> latestVersionListMap = findLatestVersion(resourceDataList); + resCollection = latestVersionListMap.values(); + } + return Either.left(resCollection); + } + } finally { + titanGenericDao.commit(); + } + + } + + public Either<List<Component>, StorageOperationStatus> getLatestVersionNotAbstractComponents(boolean isAbstract, Boolean isHighest, ComponentTypeEnum componentTypeEnum, String internalComponentType, List<String> componentUids) { + try { + List<Component> result = new ArrayList<>(); + Map<String, ResourceTypeEnum> componentUidsMap = new HashMap<>(); + if (componentUids == null) { + Either<Collection<ComponentMetadataData>, StorageOperationStatus> resourceNodes = getLatestVersionNotAbstractComponentsMetadataOnly(isAbstract, isHighest, componentTypeEnum, internalComponentType); + if (resourceNodes.isRight()) { + return Either.right(resourceNodes.right().value()); + } + Collection<ComponentMetadataData> collection = resourceNodes.left().value(); + + if (collection == null) { + componentUids = new ArrayList<>(); + } else { + componentUids = collection.stream().map(p -> p.getMetadataDataDefinition().getUniqueId()).collect(Collectors.toList()); + // collection.forEach(p -> { + // if (NodeTypeEnum.Resource.getName().equals(p.getLabel())) + // { + // componentUidsMap.put(p.getMetadataDataDefinition().getUniqueId(), + // ((ResourceMetadataDataDefinition) + // p.getMetadataDataDefinition()).getResourceType()); + // } + // }); + + } + + } + if (false == componentUids.isEmpty()) { + + Manager manager = new Manager(); + int numberOfWorkers = 5; + + manager.init(numberOfWorkers); + for (String componentUid : componentUids) { + ComponentParametersView componentParametersView = buildComponentViewForNotAbstract(); + // ResourceTypeEnum type = + // componentUidsMap.get(componentUid); + // if (type != null && ResourceTypeEnum.VL.equals(type)) { + if (internalComponentType != null && "vl".equalsIgnoreCase(internalComponentType)) { + componentParametersView.setIgnoreCapabilities(false); + componentParametersView.setIgnoreRequirements(false); + } + manager.addJob(new Job() { + @Override + public Either<Component, StorageOperationStatus> doWork() { + // long start = System.currentTimeMillis(); + Either<Component, StorageOperationStatus> component = getComponent(componentUid, componentParametersView, false); + // long stop = System.currentTimeMillis(); + // log.info("********** Time calculation in ms: + // getComponent single {}", (stop-start)); + return component; + } + }); + } + LinkedBlockingQueue<Either<Component, StorageOperationStatus>> res = manager.start(); + + for (Either<Component, StorageOperationStatus> resource : res) { + if (resource == null) { + if (log.isDebugEnabled()) + log.debug("Failed to fetch resource returned null "); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resource.isRight()) { + if (log.isDebugEnabled()) + log.debug("Failed to fetch resource for error is {}", resource.right().value()); + return Either.right(resource.right().value()); + } + Component component = resource.left().value(); + component.setContactId(null); + component.setCreationDate(null); + component.setCreatorUserId(null); + component.setCreatorFullName(null); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(null); + component.setLastUpdaterFullName(null); + component.setNormalizedName(null); + result.add(resource.left().value()); + } + + if (componentUids.size() != result.size()) { + if (log.isDebugEnabled()) + log.debug("one of the workers failed to complete job "); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + return Either.left(result); + + } finally { + titanGenericDao.commit(); + } + } + + private ComponentParametersView buildComponentViewForNotAbstract() { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + // componentParametersView.setIgnoreRequirements(false); + // componentParametersView.setIgnoreCapabilities(false); + componentParametersView.setIgnoreCategories(false); + componentParametersView.setIgnoreAllVersions(false); + componentParametersView.setIgnoreAllVersions(false); + return componentParametersView; + } + + protected TitanOperationStatus setCapabilitiesFromGraph(String uniqueId, Component component, NodeTypeEnum nodeType) { + TitanOperationStatus titanStatus; + Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherCapabilities = getCapabilities(component, nodeType, true); + if (eitherCapabilities.isLeft()) { + titanStatus = TitanOperationStatus.OK; + Map<String, List<CapabilityDefinition>> capabilities = eitherCapabilities.left().value(); + if (capabilities != null && !capabilities.isEmpty()) { + component.setCapabilities(capabilities); + } + } else { + titanStatus = eitherCapabilities.right().value(); + } + return titanStatus; + } + + protected TitanOperationStatus setRequirementsFromGraph(String uniqueId, Component component, NodeTypeEnum nodeType) { + TitanOperationStatus status; + Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherRequirements = getRequirements(component, nodeType, false); + if (eitherRequirements.isLeft()) { + status = TitanOperationStatus.OK; + Map<String, List<RequirementDefinition>> requirements = eitherRequirements.left().value(); + if (requirements != null && !requirements.isEmpty()) { + component.setRequirements(requirements); + } + } else { + status = eitherRequirements.right().value(); + } + return status; + } + + protected boolean isComponentExist(String componentId, NodeTypeEnum nodeType) { + boolean result = true; + Either<TitanVertex, TitanOperationStatus> compVertex = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (compVertex.isRight()) { + log.debug("failed to fetch vertex of component data for id {}", componentId); + result = false; + + } + return result; + } + + <T> Either<T, StorageOperationStatus> getLightComponent(String id, NodeTypeEnum nodeType, boolean inTransaction) { + Either<Component, StorageOperationStatus> metadataComponent = getMetadataComponent(id, nodeType, inTransaction); + if (metadataComponent.isRight()) { + + } + T component = null; + try { + log.debug("Starting to build light component of type {}, id {}", nodeType, id); + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + } + TitanGraph titanGraph = graphResult.left().value(); + Iterable<TitanVertex> vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), id).vertices(); + if (vertecies != null) { + Iterator<TitanVertex> iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex vertex = iterator.next(); + Map<String, Object> resourceProperties = titanGenericDao.getProperties(vertex); + ComponentMetadataData componentMetadataData = GraphElementFactory.createElement(nodeType.getName(), GraphElementTypeEnum.Node, resourceProperties, ComponentMetadataData.class); + component = (T) convertComponentMetadataDataToComponent(componentMetadataData); + + // get creator + Iterator<Edge> iterCreator = vertex.edges(Direction.IN, GraphEdgeLabels.CREATOR.name()); + if (iterCreator.hasNext() == false) { + log.debug("no creator was defined for component {}", id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Vertex vertexCreator = iterCreator.next().outVertex(); + UserData creator = GraphElementFactory.createElement(NodeTypeEnum.User.getName(), GraphElementTypeEnum.Node, titanGenericDao.getProperties(vertexCreator), UserData.class); + log.debug("Build component : set creator userId to {}", creator.getUserId()); + String fullName = buildFullName(creator); + log.debug("Build component : set creator full name to {}", fullName); + ((Component) component).setCreatorUserId(creator.getUserId()); + ((Component) component).setCreatorFullName(fullName); + + // get modifier + Iterator<Edge> iterModifier = vertex.edges(Direction.IN, GraphEdgeLabels.LAST_MODIFIER.name()); + + if (iterModifier.hasNext() == false) { + log.debug("no modifier was defined for component {}", id); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Vertex vertexModifier = iterModifier.next().outVertex(); + UserData modifier = GraphElementFactory.createElement(NodeTypeEnum.User.getName(), GraphElementTypeEnum.Node, titanGenericDao.getProperties(vertexModifier), UserData.class); + log.debug("Build component : set last modifier userId to {}", creator.getUserId()); + fullName = buildFullName(modifier); + log.debug("Build component : set last modifier full name to {}", fullName); + ((Component) component).setLastUpdaterUserId(modifier.getUserId()); + ((Component) component).setLastUpdaterFullName(fullName); + + // get category + TitanOperationStatus status = setComponentCategoriesFromGraph((Component) component); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + log.debug("Ended to build light component of type {}, id {}", nodeType, id); + return Either.left(component); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + Either<Component, StorageOperationStatus> getMetadataComponent(String id, NodeTypeEnum nodeType, boolean inTransaction) { + Component component = null; + try { + log.debug("Starting to build metadata component of type {}, id {}", nodeType, id); + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + } + TitanGraph titanGraph = graphResult.left().value(); + Iterable<TitanVertex> vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(nodeType), id).vertices(); + if (vertecies != null) { + Iterator<TitanVertex> iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex vertex = iterator.next(); + Map<String, Object> resourceProperties = titanGenericDao.getProperties(vertex); + ComponentMetadataData componentMetadataData = GraphElementFactory.createElement(nodeType.getName(), GraphElementTypeEnum.Node, resourceProperties, ComponentMetadataData.class); + component = convertComponentMetadataDataToComponent(componentMetadataData); + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } else { + // Nothing found + log.debug("Component with id {} not found", id); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + log.debug("Ended to build metadata component of type {}, id {}", nodeType, id); + return Either.left(component); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + public Either<Integer, StorageOperationStatus> getComponentInstanceCoutner(String origServiceId, NodeTypeEnum nodeType) { + Either<Integer, StorageOperationStatus> result; + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), origServiceId); + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of component metadata, nodeType:{} , id: {}", nodeType, origServiceId); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(vertexService.right().value())); + return result; + } + Vertex vertex = vertexService.left().value(); + Integer instanceCounter = vertex.value(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty()); + return Either.left(instanceCounter); + } + + protected TitanOperationStatus setComponentInstancesPropertiesFromGraph(String uniqueId, Component component) { + + List<ComponentInstance> resourceInstances = component.getComponentInstances(); + + Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties = new HashMap<>(); + + Map<String, List<PropertyDefinition>> alreadyProcessedResources = new HashMap<>(); + + Map<String, List<ComponentInstanceProperty>> alreadyProcessedInstances = new HashMap<>(); + + Map<String, ImmutablePair<ComponentInstance, Integer>> processedInstances = new HashMap<>(); + + if (resourceInstances != null) { + + for (ComponentInstance resourceInstance : resourceInstances) { + + List<String> path = new ArrayList<>(); + path.add(resourceInstance.getUniqueId()); + Either<List<ComponentInstanceProperty>, TitanOperationStatus> componentInstanceProperties = componentInstanceOperation.getComponentInstanceProperties(resourceInstance, alreadyProcessedResources, alreadyProcessedInstances, + processedInstances, path); + + if (componentInstanceProperties.isRight()) { + TitanOperationStatus status = componentInstanceProperties.right().value(); + if (status != TitanOperationStatus.OK) { + return status; + } + } + + List<ComponentInstanceProperty> listOfProps = componentInstanceProperties.left().value(); + String resourceInstanceUid = resourceInstance.getUniqueId(); + resourceInstancesProperties.put(resourceInstanceUid, listOfProps); + + // alreadyProcessedInstances.put(resourceInstance.getUniqueId(), + // resourceInstance); + + processedInstances.put(resourceInstance.getUniqueId(), new ImmutablePair<ComponentInstance, Integer>(resourceInstance, path.size())); + path.remove(path.size() - 1); + + } + + } + + Either<Map<String, Map<String, ComponentInstanceProperty>>, TitanOperationStatus> findAllPropertiesValuesOnInstances = componentInstanceOperation.findAllPropertyValueOnInstances(processedInstances); + // 1. check status + if (findAllPropertiesValuesOnInstances.isRight()) { + TitanOperationStatus status = findAllPropertiesValuesOnInstances.right().value(); + if (status != TitanOperationStatus.OK) { + return status; + } + } + // 2. merge data from rules on properties (resourceInstancesProperties) + propertyOperation.updatePropertiesByPropertyValues(resourceInstancesProperties, findAllPropertiesValuesOnInstances.left().value()); + + component.setComponentInstancesProperties(resourceInstancesProperties); + + return TitanOperationStatus.OK; + } + + protected TitanOperationStatus setComponentInstancesInputsFromGraph(String uniqueId, Component component) { + + Map<String, List<ComponentInstanceInput>> resourceInstancesInputs = new HashMap<>(); + TitanOperationStatus status = TitanOperationStatus.OK; + List<ComponentInstance> componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + for (ComponentInstance resourceInstance : componentInstances) { + Either<List<ComponentInstanceInput>, TitanOperationStatus> eitherRIAttributes = inputOperation.getAllInputsOfResourceInstance(resourceInstance); + if (eitherRIAttributes.isRight()) { + if (eitherRIAttributes.right().value() != TitanOperationStatus.NOT_FOUND) { + status = eitherRIAttributes.right().value(); + break; + } + } else { + resourceInstancesInputs.put(resourceInstance.getUniqueId(), eitherRIAttributes.left().value()); + } + } + if (!resourceInstancesInputs.isEmpty()) + component.setComponentInstancesInputs(resourceInstancesInputs); + } + + return status; + } + + public Either<String, StorageOperationStatus> getInvariantUUID(NodeTypeEnum nodeType, String componentId, boolean inTransaction) { + Either<String, StorageOperationStatus> res = null; + try { + Either<TitanVertex, TitanOperationStatus> vertexByProperty = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId); + if (vertexByProperty.isRight()) { + TitanOperationStatus status = vertexByProperty.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + res = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + Vertex v = vertexByProperty.left().value(); + String invariantUUID = v.value(GraphPropertiesDictionary.INVARIANT_UUID.getProperty()); + + if (invariantUUID == null || invariantUUID.isEmpty()) { + + log.info("The component {} has empty invariant UUID.", componentId); + res = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.INVALID_ELEMENT)); + + } + res = Either.left(invariantUUID); + } + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + return res; + } + + protected TitanOperationStatus setGroupsFromGraph(String uniqueId, Component component, NodeTypeEnum nodeTypeEnum) { + + Either<List<GroupDefinition>, TitanOperationStatus> res = groupOperation.getAllGroupsFromGraph(uniqueId, nodeTypeEnum); + if (res.isRight()) { + TitanOperationStatus status = res.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return TitanOperationStatus.OK; + } else { + return status; + } + } + component.setGroups(res.left().value()); + + return TitanOperationStatus.OK; + + } + + protected TitanOperationStatus setComponentInputsFromGraph(String uniqueId, Component component, boolean inTransaction) { + + List<InputDefinition> inputs = new ArrayList<>(); + TitanOperationStatus status = inputsOperation.findAllResourceInputs(uniqueId, inputs); + if (status == TitanOperationStatus.OK) { + component.setInputs(inputs); + } + + return status; + + } + + protected StorageOperationStatus deleteGroups(NodeTypeEnum nodeType, String componentId) { + + Either<List<GroupDefinition>, StorageOperationStatus> deleteRes = groupOperation.deleteAllGroups(componentId, nodeType, true); + + if (deleteRes.isRight()) { + StorageOperationStatus status = deleteRes.right().value(); + return status; + } + + return StorageOperationStatus.OK; + + } + + protected StorageOperationStatus removeInputsFromComponent(NodeTypeEnum typeEnum, Component component) { + Either<Map<String, InputDefinition>, StorageOperationStatus> deleteAllInputsAssociatedToNode = inputsOperation.deleteAllInputsAssociatedToNode(typeEnum, component.getUniqueId()); + return deleteAllInputsAssociatedToNode.isRight() ? deleteAllInputsAssociatedToNode.right().value() : StorageOperationStatus.OK; + } + + protected TitanOperationStatus associateInputsToComponent(NodeTypeEnum nodeType, ComponentMetadataData resourceData, List<InputDefinition> properties) { + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map<String, InputDefinition> convertedProperties = new HashMap<>(); + + if (properties != null) { + for (InputDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + + Either<List<InputDefinition>, TitanOperationStatus> operationStatus = inputsOperation.addInputsToGraph(resourceData.getMetadataDataDefinition().getUniqueId(), nodeType, convertedProperties, allDataTypes.left().value()); + if (operationStatus.isLeft()) + return TitanOperationStatus.OK; + else + return operationStatus.right().value(); + } + + return TitanOperationStatus.OK; + + } + + protected TitanOperationStatus associateInputsToComponent(TitanVertex metadataVertex, String componentId, List<InputDefinition> properties) { + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map<String, InputDefinition> convertedProperties = new HashMap<>(); + + if (properties != null) { + for (InputDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + + return inputsOperation.addInputsToGraph(metadataVertex, componentId, convertedProperties, allDataTypes.left().value()); + } + + return TitanOperationStatus.OK; + + } + + public Either<List<ComponentInstance>, StorageOperationStatus> getAllComponentInstncesMetadata(String componentId, NodeTypeEnum nodeType) { + Instant start = Instant.now(); + Either<List<ComponentInstance>, StorageOperationStatus> resourceInstancesOfService = componentInstanceOperation.getAllComponentInstancesMetadataOnly(componentId, nodeType); + Instant end = Instant.now(); + log.debug("TOTAL TIME BL GET INSTANCES: {}", Duration.between(start, end)); // prints + // PT1M3.553S + return resourceInstancesOfService; + } + + @Deprecated + public Either<List<Component>, ActionStatus> getComponentsFromCacheForCatalog(Set<String> components, ComponentTypeEnum componentType) { + + Either<ImmutableTriple<List<Component>, List<Component>, Set<String>>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, componentType); + if (componentsForCatalog.isLeft()) { + ImmutableTriple<List<Component>, List<Component>, Set<String>> immutableTriple = componentsForCatalog.left().value(); + List<Component> foundComponents = immutableTriple.getLeft(); + + if (foundComponents != null) { + // foundComponents.forEach(p -> result.add((Resource)p)); + log.debug("The number of {}s added to catalog from cache is {}", componentType.name().toLowerCase(), foundComponents.size()); + + } + List<Component> foundDirtyComponents = immutableTriple.getMiddle(); + Set<String> nonCachedComponents = immutableTriple.getRight(); + int numberDirtyResources = foundDirtyComponents == null ? 0 : foundDirtyComponents.size(); + int numberNonCached = nonCachedComponents == null ? 0 : nonCachedComponents.size(); + log.debug("The number of left {}s for catalog is {}", componentType.name().toLowerCase(), numberDirtyResources + numberNonCached); + return Either.left(foundComponents); + } + + return Either.right(componentsForCatalog.right().value()); + } + + public <T extends ComponentMetadataData> Either<List<T>, TitanOperationStatus> getListOfHighestComponents(NodeTypeEnum nodeTypeEnum, Class<T> clazz) { + + long startFetchAllStates = System.currentTimeMillis(); + Map<String, Object> propertiesToMatchHigest = new HashMap<>(); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + Either<List<T>, TitanOperationStatus> allHighestStates = titanGenericDao.getByCriteria(nodeTypeEnum, propertiesToMatchHigest, clazz); + if (allHighestStates.isRight() && allHighestStates.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(allHighestStates.right().value()); + } + long endFetchAllStates = System.currentTimeMillis(); + + if (allHighestStates.isRight()) { + return Either.left(new ArrayList<>()); + } + List<T> services = allHighestStates.left().value(); + + List<T> certifiedHighest = new ArrayList<>(); + List<T> notCertifiedHighest = new ArrayList<>(); + for (T reData : services) { + if (reData.getMetadataDataDefinition().getState().equals(LifecycleStateEnum.CERTIFIED.name())) { + certifiedHighest.add(reData); + } else { + notCertifiedHighest.add(reData); + } + } + + log.debug("Fetch catalog {}s all states: certified {}, noncertified {}", nodeTypeEnum.getName(), certifiedHighest.size(), notCertifiedHighest.size()); + log.debug("Fetch catalog {}s all states from graph took {} ms", nodeTypeEnum.getName(), endFetchAllStates - startFetchAllStates); + + HashMap<String, String> serviceNames = new HashMap<>(); + for (T data : notCertifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + serviceNames.put(serviceName, serviceName); + } + + for (T data : certifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (!serviceNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } + + return Either.left(notCertifiedHighest); + } + + protected <T extends Component> Either<T, ActionStatus> getComponentFromCacheIfUpToDate(String uniqueId, ComponentMetadataData componentMetadataData, ComponentParametersView componentParametersView, Class<T> clazz, + ComponentTypeEnum componentTypeEnum) { + + long start = System.currentTimeMillis(); + try { + + long lastModificationTime = componentMetadataData.getMetadataDataDefinition().getLastUpdateDate(); + Either<Component, ActionStatus> cacheComponentRes = this.componentCache.getComponent(uniqueId, lastModificationTime); + if (cacheComponentRes.isLeft()) { + Component cachedComponent = cacheComponentRes.left().value(); + + // Must calculate allVersions + if (false == componentParametersView.isIgnoreAllVersions()) { + Class<? extends ComponentMetadataData> clazz1 = null; + switch (componentTypeEnum) { + case RESOURCE: + clazz1 = ResourceMetadataData.class; + break; + case SERVICE: + clazz1 = ServiceMetadataData.class; + break; + case PRODUCT: + clazz1 = ProductMetadataData.class; + break; + default: + break; + } + if (clazz1 != null) { + // long startGetAllVersions = + // System.currentTimeMillis(); + Either<Map<String, String>, TitanOperationStatus> versionList = getVersionList(componentTypeEnum.getNodeType(), cachedComponent.getVersion(), cachedComponent.getUUID(), cachedComponent.getSystemName(), clazz1); + // log.debug("Fetch all versions for component {} took + // {} ms", cachedComponent.getUniqueId(), + // System.currentTimeMillis() - startGetAllVersions); + if (versionList.isRight()) { + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Map<String, String> allVersions = versionList.left().value(); + cachedComponent.setAllVersions(allVersions); + } else { + return Either.right(ActionStatus.GENERAL_ERROR); + } + } + if (componentParametersView != null) { + cachedComponent = componentParametersView.filter(cachedComponent, componentTypeEnum); + } + return Either.left(clazz.cast(cachedComponent)); + } + + return Either.right(cacheComponentRes.right().value()); + + } finally { + log.trace("Fetch component {} with uid {} from cache took {} ms", componentTypeEnum.name().toLowerCase(), uniqueId, System.currentTimeMillis() - start); + } + } + + public Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> getComponentsFromCacheForCatalog(Map<String, Long> components, ComponentTypeEnum componentType) { + + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, componentType); + if (componentsForCatalog.isLeft()) { + ImmutablePair<List<Component>, Set<String>> immutablePair = componentsForCatalog.left().value(); + List<Component> foundComponents = immutablePair.getLeft(); + + if (foundComponents != null) { + // foundComponents.forEach(p -> result.add((Resource)p)); + log.debug("The number of {}s added to catalog from cache is {}", componentType.name().toLowerCase(), foundComponents.size()); + } + Set<String> leftComponents = immutablePair.getRight(); + int numberNonCached = leftComponents == null ? 0 : leftComponents.size(); + log.debug("The number of left {}s for catalog is {}", componentType.name().toLowerCase(), numberNonCached); + + ImmutablePair<List<Component>, Set<String>> result = new ImmutablePair<List<Component>, Set<String>>(foundComponents, leftComponents); + return Either.left(result); + } + + return Either.right(componentsForCatalog.right().value()); + } + + /** + * + * @param component + * @param inTransaction + * @param titanGenericDao + * @param clazz + * @return + */ + public <T> Either<T, StorageOperationStatus> updateComponentFilterResult(Component component, boolean inTransaction, TitanGenericDao titanGenericDao, Class<T> clazz, NodeTypeEnum type, ComponentParametersView filterResult) { + Either<T, StorageOperationStatus> result = null; + + try { + + log.debug("In updateComponent. received component uid = {}", (component == null ? null : component.getUniqueId())); + if (component == null) { + log.error("Service object is null"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + ComponentMetadataData componentData = getMetaDataFromComponent(component); + + log.debug("After converting component to componentData. ComponentData = {}", componentData); + + if (componentData.getUniqueId() == null) { + log.error("Resource id is missing in the request."); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Either<Integer, StorageOperationStatus> counterStatus = this.getComponentInstanceCoutner(component.getUniqueId(), component.getComponentType().getNodeType()); + + if (counterStatus.isRight()) { + + log.error("Cannot find componentInstanceCounter for component {} in the graph. Status is {}", componentData.getUniqueId(), counterStatus); + // result = sendError(status, + // StorageOperationStatus.USER_NOT_FOUND); + return result; + } + + componentData.setComponentInstanceCounter(counterStatus.left().value()); + + String modifierUserId = component.getLastUpdaterUserId(); + if (modifierUserId == null || modifierUserId.isEmpty()) { + log.error("userId is missing in the request."); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + Either<UserData, TitanOperationStatus> findUser = findUser(modifierUserId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. Status is {}", modifierUserId, status); + // result = sendError(status, + // StorageOperationStatus.USER_NOT_FOUND); + return result; + } + + UserData modifierUserData = findUser.left().value(); + String resourceId = component.getUniqueId(); + + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreCategories(false); + componentParametersView.setIgnoreDerivedFrom(false); + componentParametersView.setIgnoreArtifacts(false); + Either<T, StorageOperationStatus> currentComponentResult = this.getComponent(resourceId, componentParametersView, inTransaction); + if (currentComponentResult.isRight()) { + log.error("Cannot find resource with id {} in the graph.", resourceId); + result = Either.right(currentComponentResult.right().value()); + return result; + } + + Component currentComponent = (Component) currentComponentResult.left().value(); + String currentModifier = currentComponent.getLastUpdaterUserId(); + + if (currentModifier.equals(modifierUserData.getUniqueId())) { + log.debug("Graph LAST MODIFIER edge should not be changed since the modifier is the same as the last modifier."); + } else { + log.debug("Going to update the last modifier user of the resource from {} to {}", currentModifier, modifierUserId); + StorageOperationStatus status = moveLastModifierEdge(component, componentData, modifierUserData, type); + log.debug("Finish to update the last modifier user of the resource from {} to {}. Status is {}", currentModifier, modifierUserId, status); + if (status != StorageOperationStatus.OK) { + result = Either.right(status); + return result; + } + } + final long currentTimeMillis = System.currentTimeMillis(); + log.debug("Going to update the last Update Date of the resource from {} to {}", component.getLastUpdateDate(), currentTimeMillis); + component.setLastUpdateDate(currentTimeMillis); + + StorageOperationStatus checkCategories = validateCategories(currentComponent, component, componentData, type); + if (checkCategories != StorageOperationStatus.OK) { + result = Either.right(checkCategories); + return result; + } + + List<String> tags = component.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either<List<TagData>, StorageOperationStatus> tagsResult = createNewTagsList(tags); + if (tagsResult.isRight()) { + result = Either.right(tagsResult.right().value()); + return result; + } + List<TagData> tagsToCreate = tagsResult.left().value(); + if (tagsToCreate != null && !tagsToCreate.isEmpty()) { + tagsToCreate = ImmutableSet.copyOf(tagsToCreate).asList(); + for (TagData tagData : tagsToCreate) { + log.debug("Before creating tag {}", tagData); + Either<TagData, TitanOperationStatus> createTagResult = titanGenericDao.createNode(tagData, TagData.class); + if (createTagResult.isRight()) { + TitanOperationStatus status = createTagResult.right().value(); + log.error("Cannot find tag {} in the graph. Status is {}", tagData, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("After creating tag {}", tagData); + } + } + } + + Either<ComponentMetadataData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(componentData, ComponentMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource {}. Status is {}", component.getUniqueId(), updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + + ComponentMetadataData updatedResourceData = updateNode.left().value(); + log.debug("ComponentData After update is {}", updatedResourceData); + + // DE230195 in case resource name changed update TOSCA artifacts + // file names accordingly + String newSystemName = updatedResourceData.getMetadataDataDefinition().getSystemName(); + if (newSystemName != null && !newSystemName.equals(currentComponent.getSystemName())) { + Map<String, ArtifactDefinition> toscaArtifacts = component.getToscaArtifacts(); + if (toscaArtifacts != null) { + for (Entry<String, ArtifactDefinition> artifact : toscaArtifacts.entrySet()) { + Either<ArtifactData, StorageOperationStatus> updateName = generateAndUpdateToscaFileName(component.getComponentType().getValue().toLowerCase(), newSystemName, updatedResourceData.getMetadataDataDefinition().getUniqueId(), + type, artifact.getValue()); + if (updateName.isRight()) { + result = Either.right(updateName.right().value()); + return result; + } + } + } + + } + + if (component.getComponentType().equals(ComponentTypeEnum.RESOURCE)) { + updateDerived(component, currentComponent, componentData, component.getClass()); + } + + Either<T, StorageOperationStatus> updatedResource = getComponent(component.getUniqueId(), filterResult, inTransaction); + if (updatedResource.isRight()) { + log.error("Resource id is missing in the request. status is {}", updatedResource.right().value()); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + T updatedResourceValue = updatedResource.left().value(); + result = Either.left(updatedResourceValue); + + if (log.isDebugEnabled()) { + // String json = prettyJson.toJson(result.left().value()); + // log.debug("Resource retrieved after update is {}", json); + } + + return result; + + } finally { + + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("updateComponent operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("updateComponent operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java new file mode 100644 index 0000000000..aafa4ba444 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.operations.api.IConsumerOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ConsumerData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("consumer-operation") +public class ConsumerOperation implements IConsumerOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + private static Logger log = LoggerFactory.getLogger(ConsumerOperation.class.getName()); + + public ConsumerOperation() { + } + + @Override + public Either<ConsumerData, StorageOperationStatus> getCredentials(String consumerName) { + Either<ConsumerData, StorageOperationStatus> result = null; + log.debug("retriving Credentials for: {}.", consumerName); + Either<ConsumerData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class); + if (getNode.isRight()) { + TitanOperationStatus status = getNode.right().value(); + log.error("Error returned after get Consumer Data node " + consumerName + ". status returned is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData consumerData = getNode.left().value(); + return Either.left(consumerData); + } + + @Override + public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData) { + return createCredentials(consumerData, false); + } + + @Override + public Either<ConsumerData, StorageOperationStatus> createCredentials(ConsumerData consumerData, boolean inTransaction) { + Either<ConsumerData, StorageOperationStatus> result = null; + try { + log.debug("creating Credentials for: {}.", consumerData.getUniqueId()); + Either<ConsumerData, TitanOperationStatus> createNode = titanGenericDao.createNode(consumerData, ConsumerData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating Consumer Data node " + consumerData.getUniqueId() + ". status returned is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData createdConsumerData = createNode.left().value(); + result = Either.left(createdConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + } + + @Override + public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName) { + return deleteCredentials(consumerName, false); + } + + @Override + public Either<ConsumerData, StorageOperationStatus> deleteCredentials(String consumerName, boolean inTransaction) { + Either<ConsumerData, StorageOperationStatus> result = null; + try { + log.debug("delete Credentials for: {}", consumerName); + Either<ConsumerData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(GraphPropertiesDictionary.CONSUMER_NAME.getProperty(), consumerName, ConsumerData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = deleteNode.right().value(); + log.error("Error returned after delete Consumer Data node {}. Status returned is {}", consumerName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + ConsumerData deletedConsumerData = deleteNode.left().value(); + result = Either.left(deletedConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + + } + + @Override + public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData) { + return updateCredentials(consumerData, false); + } + + @Override + public Either<ConsumerData, StorageOperationStatus> updateCredentials(ConsumerData consumerData, boolean inTransaction) { + + Either<ConsumerData, StorageOperationStatus> result = null; + try { + log.debug("update Credentials for: {}.", consumerData.getUniqueId()); + Either<ConsumerData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(consumerData, ConsumerData.class); + if (updateNode.isRight()) { + TitanOperationStatus status = updateNode.right().value(); + log.error("Error returned after delete Consumer Data node {}. Status returned is {}", consumerData.getUniqueId(), status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + ConsumerData updatedConsumerData = updateNode.left().value(); + result = Either.left(updatedConsumerData); + return result; + } finally { + handleTransaction(inTransaction, result); + } + } + + private void handleTransaction(boolean inTransaction, Either<ConsumerData, StorageOperationStatus> result) { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java new file mode 100644 index 0000000000..1420ce08d8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java @@ -0,0 +1,115 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("csar-operation") +public class CsarOperation { + + private static Logger log = LoggerFactory.getLogger(CsarOperation.class.getName()); + + @javax.annotation.Resource + private OnboardingClient onboardingClient; + + public static void main(String[] args) { + + CsarOperation csarOperation = new CsarOperation(); + csarOperation.init(); + + String csarUuid = "70025CF6081B489CA7B1CBA583D5278D"; + Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null); + System.out.println(csar.left().value()); + + } + + @PostConstruct + public void init() { + + } + + // Mock returning a file from the file system until we have API from onboarding + public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) { + File dir = new File("/var/tmp/mockCsar"); + FileFilter fileFilter = new WildcardFileFilter("*.csar"); + File[] files = dir.listFiles(fileFilter); + for (int i = 0; i < files.length; i++) { + File csar = files[i]; + if (csar.getName().startsWith(csarUuid)) { + log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid); + byte[] data; + try { + data = Files.readAllBytes(csar.toPath()); + } catch (IOException e) { + log.debug("Error reading mock file for CSAR, error: {}", e); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Map<String, byte[]> readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } + } + log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid); + return Either.right(StorageOperationStatus.CSAR_NOT_FOUND); + } + + /** + * get csar from remote repository + * + * @param csarUuid + * @return + */ + public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, User user) { + + Either<Map<String, byte[]>, StorageOperationStatus> result = onboardingClient.getCsar(csarUuid, + user.getUserId()); + + if (result.isRight()) { + log.debug("Cannot find csar {}. Status returned is {}", csarUuid, result.right().value()); + } else { + Map<String, byte[]> values = result.left().value(); + if (values != null) { + log.debug("The returned files are {}", values.keySet()); + } + } + + return result; + } + + public OnboardingClient getOnboardingClient() { + return onboardingClient; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java new file mode 100644 index 0000000000..b887c5b212 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import org.openecomp.sdc.be.dao.api.ResourceUploadStatus; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +public class DaoStatusConverter { + + public static StorageOperationStatus convertTitanStatusToStorageStatus(TitanOperationStatus titanStatus) { + + if (titanStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + + switch (titanStatus) { + + case OK: + return StorageOperationStatus.OK; + + case NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + case NOT_CREATED: + return StorageOperationStatus.SCHEMA_ERROR; + + case INDEX_CANNOT_BE_CHANGED: + return StorageOperationStatus.SCHEMA_ERROR; + + case MISSING_UNIQUE_ID: + return StorageOperationStatus.BAD_REQUEST; + case ALREADY_LOCKED: + return StorageOperationStatus.FAILED_TO_LOCK_ELEMENT; + + case TITAN_SCHEMA_VIOLATION: + return StorageOperationStatus.SCHEMA_VIOLATION; + + case INVALID_ID: + return StorageOperationStatus.INVALID_ID; + case MATCH_NOT_FOUND: + return StorageOperationStatus.MATCH_NOT_FOUND; + + case ILLEGAL_ARGUMENT: + return StorageOperationStatus.BAD_REQUEST; + // case HTTP_PROTOCOL_ERROR: + // return StorageOperationStatus.HTTP_PROTOCOL_ERROR; + // case DB_NOT_AVAILABLE: + // return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + // case DB_READ_ONLY: + // return StorageOperationStatus.READ_ONLY_STORAGE; + // case BAD_REQUEST: + // return StorageOperationStatus.BAD_REQUEST; + // case LEGACY_INDEX_ERROR: + // return StorageOperationStatus.STORAGE_LEGACY_INDEX_ERROR; + // case SCHEMA_ERROR: + // return StorageOperationStatus.SCHEMA_ERROR; + // case TRANSACTION_ERROR: + // return StorageOperationStatus.TRANSACTION_ERROR; + // case EXECUTION_FAILED: + // return StorageOperationStatus.EXEUCTION_FAILED; + case ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case PROPERTY_NAME_ALREADY_EXISTS: + return StorageOperationStatus.PROPERTY_NAME_ALREADY_EXISTS; + case INVALID_PROPERTY: + return StorageOperationStatus.INVALID_PROPERTY; + // case WRONG_INPUT: + // return StorageOperationStatus.BAD_REQUEST; + // case GENERAL_ERROR: + // return StorageOperationStatus.GENERAL_ERROR; + // case NOT_SUPPORTED: + // return StorageOperationStatus.OPERATION_NOT_SUPPORTED; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + + } + + public static StorageOperationStatus convertRsrcUploadStatusToStorageStatus( + ResourceUploadStatus resourceUploadStatus) { + if (resourceUploadStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + switch (resourceUploadStatus) { + case OK: + return StorageOperationStatus.OK; + case ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case NOT_EXIST: + return StorageOperationStatus.ARTIFACT_NOT_FOUND; + case SERVICE_NOT_EXIST: + case COMPONENT_NOT_EXIST: + return StorageOperationStatus.NOT_FOUND; + default: + return StorageOperationStatus.GENERAL_ERROR; + } + } + + public static StorageOperationStatus convertCassandraStatusToStorageStatus(CassandraOperationStatus status) { + if (status == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + switch (status) { + case OK: + return StorageOperationStatus.OK; + case CLUSTER_NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + case KEYSPACE_NOT_CONNECTED: + return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java new file mode 100644 index 0000000000..248a1d0460 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java @@ -0,0 +1,902 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanGraph; +//import com.tinkerpop.blueprints.Vertex; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("element-operation") +public class ElementOperation implements IElementOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public ElementOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ElementOperation.class.getName()); + + /* + * Old flow + */ + @Override + public Either<List<CategoryDefinition>, ActionStatus> getAllServiceCategories() { + return getAllCategories(NodeTypeEnum.ServiceNewCategory, false); + } + + @Override + public Either<List<CategoryDefinition>, ActionStatus> getAllResourceCategories() { + return getAllCategories(NodeTypeEnum.ResourceNewCategory, false); + } + + @Override + public Either<List<CategoryDefinition>, ActionStatus> getAllProductCategories() { + return getAllCategories(NodeTypeEnum.ProductCategory, false); + } + /* + * + */ + + /* + * New flow + */ + @Override + public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType) { + return createCategory(category, nodeType, false); + } + + @Override + public Either<CategoryDefinition, ActionStatus> createCategory(CategoryDefinition category, NodeTypeEnum nodeType, + boolean inTransaction) { + Either<CategoryDefinition, ActionStatus> result = null; + category.setUniqueId(UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeType)); + CategoryData categoryData = new CategoryData(nodeType, category); + + try { + Either<CategoryData, TitanOperationStatus> createNode = titanGenericDao.createNode(categoryData, + CategoryData.class); + if (createNode.isRight()) { + TitanOperationStatus value = createNode.right().value(); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + log.debug("Problem while creating category, reason {}", value); + if (value == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS; + } + result = Either.right(actionStatus); + return result; + } + CategoryDefinition created = new CategoryDefinition(createNode.left().value().getCategoryDataDefinition()); + result = Either.left(created); + return result; + } finally { + if (inTransaction == false) { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + } + + @Override + public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, + SubCategoryDefinition subCategory, NodeTypeEnum nodeType) { + return createSubCategory(categoryId, subCategory, nodeType, false); + } + + @Override + public Either<SubCategoryDefinition, ActionStatus> createSubCategory(String categoryId, + SubCategoryDefinition subCategory, NodeTypeEnum nodeType, boolean inTransaction) { + + Either<SubCategoryDefinition, ActionStatus> result = null; + + try { + // create edge from category to sub-category + Either<CategoryData, TitanOperationStatus> categoryNode = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + if (categoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = categoryNode.right().value(); + log.debug("Problem while fetching category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND; + } + result = Either.right(actionStatus); + return result; + } + + CategoryDataDefinition categoryDataDefinition = categoryNode.left().value().getCategoryDataDefinition(); + subCategory.setUniqueId(UniqueIdBuilder.buildSubCategoryUid(categoryDataDefinition.getUniqueId(), + subCategory.getNormalizedName())); + SubCategoryData subCategoryData = new SubCategoryData(nodeType, subCategory); + + Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao.createNode(subCategoryData, + SubCategoryData.class); + if (subCategoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryNode.right().value(); + log.debug("Problem while creating category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY; + } + result = Either.right(actionStatus); + return result; + } + + Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation( + categoryNode.left().value(), subCategoryNode.left().value(), GraphEdgeLabels.SUB_CATEGORY, null); + if (relation.isRight()) { + log.debug("Problem while create relation between category and sub-category ", relation.right().value()); + result = Either.right(actionStatus); + return result; + } + SubCategoryDefinition subCategoryCreated = new SubCategoryDefinition( + subCategoryNode.left().value().getSubCategoryDataDefinition()); + result = Either.left(subCategoryCreated); + return result; + } finally { + if (inTransaction == false) { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + } + + @Override + public Either<GroupingDefinition, ActionStatus> createGrouping(String subCategoryId, GroupingDefinition grouping, + NodeTypeEnum nodeType) { + + Either<GroupingDefinition, ActionStatus> result = null; + + try { + // create edge from sub-category to grouping + Either<SubCategoryData, TitanOperationStatus> subCategoryNode = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + ActionStatus actionStatus = ActionStatus.GENERAL_ERROR; + if (subCategoryNode.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryNode.right().value(); + log.debug("Problem while fetching category, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.TITAN_SCHEMA_VIOLATION) { + actionStatus = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND; + } + result = Either.right(actionStatus); + return result; + } + + SubCategoryDataDefinition subCatData = subCategoryNode.left().value().getSubCategoryDataDefinition(); + grouping.setUniqueId( + UniqueIdBuilder.buildGroupingUid(subCatData.getUniqueId(), grouping.getNormalizedName())); + GroupingData groupingData = new GroupingData(nodeType, grouping); + + Either<GroupingData, TitanOperationStatus> groupingNode = titanGenericDao.createNode(groupingData, + GroupingData.class); + if (groupingNode.isRight()) { + TitanOperationStatus titanOperationStatus = groupingNode.right().value(); + log.debug("Problem while creating grouping, reason {}", titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + actionStatus = ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY; + } + result = Either.right(actionStatus); + return result; + } + + Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.createRelation( + subCategoryNode.left().value(), groupingNode.left().value(), GraphEdgeLabels.GROUPING, null); + if (relation.isRight()) { + log.debug("Problem while create relation between sub-category and grouping", relation.right().value()); + result = Either.right(actionStatus); + return result; + } + GroupingDefinition groupingCreated = new GroupingDefinition( + groupingNode.left().value().getGroupingDataDefinition()); + result = Either.left(groupingCreated); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either<List<CategoryDefinition>, ActionStatus> getAllCategories(NodeTypeEnum nodeType, + boolean inTransaction) { + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either<List<org.openecomp.sdc.be.resources.data.category.CategoryData>, TitanOperationStatus> either = titanGenericDao + .getAll(nodeType, org.openecomp.sdc.be.resources.data.category.CategoryData.class); + if (either.isRight() && (either.right().value() != TitanOperationStatus.NOT_FOUND)) { + log.debug("Problem while get all categories. reason - {}", either.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List<CategoryData> categoryDataList = either.isLeft() ? either.left().value() : null; + List<CategoryDefinition> categoryList = new ArrayList<CategoryDefinition>(); + if (categoryDataList != null) { + for (CategoryData elem : categoryDataList) { + CategoryDataDefinition categoryDataDefinition = elem.getCategoryDataDefinition(); + + CategoryDefinition categoryDefinition = new CategoryDefinition(categoryDataDefinition); + String categoryName = categoryDataDefinition.getName(); + log.trace("Found category {}, category type {}", categoryName, nodeType); + TitanOperationStatus setSubCategories = setSubCategories(nodeType, categoryDefinition); + if (setSubCategories != TitanOperationStatus.OK) { + log.debug("Failed to set sub-categories for category {}, category type {}, error {}", + categoryName, nodeType, setSubCategories); + return Either.right(ActionStatus.GENERAL_ERROR); + } + categoryList.add(categoryDefinition); + } + } + return Either.left(categoryList); + } finally { + if (!inTransaction) { + titanGenericDao.commit(); + } + } + } + + private TitanOperationStatus setSubCategories(NodeTypeEnum parentNodeType, CategoryDefinition parentCategory) { + NodeTypeEnum childNodeType = getChildNodeType(parentNodeType); + if (childNodeType != null) { + String categoryName = parentCategory.getName(); + log.trace("Getting sub-categories for category {}, category type {}", categoryName, parentNodeType); + Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentCategory.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, childNodeType, SubCategoryData.class); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + log.trace("Didn't find subcategories for category {}, category type {}", categoryName, + parentNodeType); + titanOperationStatus = TitanOperationStatus.OK; + } + return titanOperationStatus; + } + List<ImmutablePair<SubCategoryData, GraphEdge>> subsCategoriesData = parentNode.left().value(); + List<SubCategoryDefinition> subCategoriesDefinitions = new ArrayList<>(); + for (ImmutablePair<SubCategoryData, GraphEdge> subCatPair : subsCategoriesData) { + SubCategoryDataDefinition subCategoryDataDefinition = subCatPair.getLeft() + .getSubCategoryDataDefinition(); + SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition(subCategoryDataDefinition); + + log.trace("Found sub-category {} for category {}, category type {}", + subCategoryDataDefinition.getName(), categoryName, parentNodeType); + TitanOperationStatus setGroupings = setGroupings(childNodeType, subCategoryDefinition); + if (setGroupings != TitanOperationStatus.OK) { + log.debug("Failed to set groupings for sub-category {}, sub-category type {}, error {}", + subCategoryDataDefinition.getName(), childNodeType, setGroupings); + return TitanOperationStatus.GENERAL_ERROR; + } + subCategoriesDefinitions.add(subCategoryDefinition); + } + parentCategory.setSubcategories(subCategoriesDefinitions); + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setGroupings(NodeTypeEnum parentNodeType, SubCategoryDefinition parentSubCategory) { + NodeTypeEnum childNodeType = getChildNodeType(parentNodeType); + if (childNodeType != null) { + String subCategoryName = parentSubCategory.getName(); + log.trace("Getting groupings for subcategory {}, subcategory type {}", subCategoryName, parentNodeType); + Either<List<ImmutablePair<GroupingData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentSubCategory.getUniqueId(), + GraphEdgeLabels.GROUPING, childNodeType, GroupingData.class); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + log.trace("Didn't find groupings for subcategory {}, subcategory type {}", subCategoryName, + parentNodeType); + titanOperationStatus = TitanOperationStatus.OK; + } + return titanOperationStatus; + } + List<ImmutablePair<GroupingData, GraphEdge>> groupingData = parentNode.left().value(); + List<GroupingDefinition> groupingDefinitions = new ArrayList<>(); + for (ImmutablePair<GroupingData, GraphEdge> groupPair : groupingData) { + GroupingDataDefinition groupingDataDefinition = groupPair.getLeft().getGroupingDataDefinition(); + log.trace("Found grouping {} for sub-category {}, sub-category type {}", + groupingDataDefinition.getName(), subCategoryName, parentNodeType); + groupingDefinitions.add(new GroupingDefinition(groupingDataDefinition)); + } + parentSubCategory.setGroupings(groupingDefinitions); + } + return TitanOperationStatus.OK; + } + + private static NodeTypeEnum getChildNodeType(NodeTypeEnum parentTypeEnum) { + NodeTypeEnum res = null; + switch (parentTypeEnum) { + case ResourceNewCategory: + res = NodeTypeEnum.ResourceSubcategory; + break; + case ProductCategory: + res = NodeTypeEnum.ProductSubcategory; + break; + case ProductSubcategory: + res = NodeTypeEnum.ProductGrouping; + break; + default: + break; + } + return res; + } + + @Override + public Either<CategoryDefinition, ActionStatus> getCategory(NodeTypeEnum nodeType, String categoryId) { + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + if (categoryDataEither.isRight()) { + TitanOperationStatus titanOperationStatus = categoryDataEither.right().value(); + log.debug("Problem while get category by id {}. reason {}", categoryId, titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND); + } + return Either.right(ActionStatus.GENERAL_ERROR); + } + CategoryDataDefinition categoryDataDefinition = categoryDataEither.left().value() + .getCategoryDataDefinition(); + return Either.left(new CategoryDefinition(categoryDataDefinition)); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<SubCategoryDefinition, ActionStatus> getSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + try { + if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) { + log.debug("Unknown sub-category type {}", nodeType.name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + + Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight()) { + TitanOperationStatus titanOperationStatus = subCategoryDataEither.right().value(); + log.debug("Problem while get sub-category by id {}. reason {}", subCategoryId, titanOperationStatus); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND); + } + return Either.right(ActionStatus.GENERAL_ERROR); + } + SubCategoryDataDefinition subCategoryDataDefinition = subCategoryDataEither.left().value() + .getSubCategoryDataDefinition(); + return Either.left(new SubCategoryDefinition(subCategoryDataDefinition)); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<CategoryDefinition, ActionStatus> deleteCategory(NodeTypeEnum nodeType, String categoryId) { + Either<CategoryDefinition, ActionStatus> result = null; + try { + if (nodeType != NodeTypeEnum.ResourceNewCategory && nodeType != NodeTypeEnum.ServiceNewCategory + && nodeType != NodeTypeEnum.ProductCategory) { + log.debug("Unknown category type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either<CategoryData, TitanOperationStatus> categoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId, CategoryData.class); + if (categoryDataEither.isRight()) { + log.debug("Failed to retrieve category for id {} ", categoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable<TitanVertex> verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), categoryId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No category node for id = {}", categoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + CategoryDefinition deleted = new CategoryDefinition( + categoryDataEither.left().value().getCategoryDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either<SubCategoryDefinition, ActionStatus> deleteSubCategory(NodeTypeEnum nodeType, String subCategoryId) { + Either<SubCategoryDefinition, ActionStatus> result = null; + try { + if (nodeType != NodeTypeEnum.ResourceSubcategory && nodeType != NodeTypeEnum.ProductSubcategory) { + log.debug("Unknown sub-category type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight()) { + log.debug("Failed to retrieve sub-category for id {}", subCategoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable<TitanVertex> verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No sub-category node for id {}", subCategoryId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + ; + SubCategoryDefinition deleted = new SubCategoryDefinition( + subCategoryDataEither.left().value().getSubCategoryDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + + } + + @Override + public Either<GroupingDefinition, ActionStatus> deleteGrouping(NodeTypeEnum nodeType, String groupingId) { + Either<GroupingDefinition, ActionStatus> result = null; + try { + if (nodeType != NodeTypeEnum.ProductGrouping) { + log.debug("Unknown grouping type {}", nodeType.name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class); + if (groupingDataEither.isRight()) { + log.debug("Failed to retrieve grouping for id {}", groupingId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + Either<TitanGraph, TitanOperationStatus> graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("Couldn't fetch titan graph"); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + + TitanGraph tGraph = graph.left().value(); + + Iterable<TitanVertex> verticesArtifact = tGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId).vertices(); + Iterator<TitanVertex> iterator = verticesArtifact.iterator(); + if (!iterator.hasNext()) { + log.debug("No grouping node for id {}", groupingId); + result = Either.right(ActionStatus.GENERAL_ERROR); + return result; + } + Vertex artifactV = iterator.next(); + artifactV.remove(); + ; + GroupingDefinition deleted = new GroupingDefinition( + groupingDataEither.left().value().getGroupingDataDefinition()); + result = Either.left(deleted); + return result; + } finally { + if (result != null && result.isLeft()) { + titanGenericDao.commit(); + } else { + titanGenericDao.rollback(); + } + } + } + + @Override + public Either<Boolean, ActionStatus> isCategoryUniqueForType(NodeTypeEnum nodeType, String normalizedName) { + + Map<String, Object> properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + try { + Either<List<CategoryData>, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodeType, + properties, CategoryData.class); + if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get categories, nodeType {}, normalizedName {}, error {}", nodeType, + normalizedName, categoryEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List<CategoryData> categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null); + if (categoryList != null && categoryList.size() > 0) { + log.debug("Found category for nodeType {} with normalizedName {}", nodeType, normalizedName); + if (categoryList.size() > 1) { + log.debug("Found more than 1 unique categories for nodeType {} with normalizedName", nodeType, + normalizedName); + return Either.right(ActionStatus.GENERAL_ERROR); + } + return Either.left(false); + } else { + log.debug("Category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + normalizedName); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<Boolean, ActionStatus> isSubCategoryUniqueForCategory(NodeTypeEnum nodeType, + String subCategoryNormName, String parentCategoryId) { + + String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(parentCategoryId, subCategoryNormName); + try { + Either<SubCategoryData, TitanOperationStatus> subCategoryDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), subCategoryId, SubCategoryData.class); + if (subCategoryDataEither.isRight() + && subCategoryDataEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get sub-category with id {}, error {}", subCategoryId, + subCategoryDataEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + SubCategoryData subCategoryData = (subCategoryDataEither.isLeft() ? subCategoryDataEither.left().value() + : null); + if (subCategoryData != null) { + log.debug("Found sub-category with id {}", subCategoryId); + return Either.left(false); + } else { + log.debug("Sub-category for id {} doesn't exist in graph", subCategoryId); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<Boolean, ActionStatus> isGroupingUniqueForSubCategory(NodeTypeEnum nodeType, String groupingNormName, + String parentSubCategoryId) { + + String groupingId = UniqueIdBuilder.buildGroupingUid(parentSubCategoryId, groupingNormName); + try { + Either<GroupingData, TitanOperationStatus> groupingDataEither = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), groupingId, GroupingData.class); + if (groupingDataEither.isRight() && groupingDataEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get grouping with id {}, error {}", groupingId, + groupingDataEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + GroupingData groupingData = (groupingDataEither.isLeft() ? groupingDataEither.left().value() : null); + if (groupingData != null) { + log.debug("Found grouping with id {}", groupingId); + return Either.left(false); + } else { + log.debug("Grouping for id {} doesn't exist in graph", groupingId); + return Either.left(true); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<SubCategoryDefinition, ActionStatus> getSubCategoryUniqueForType(NodeTypeEnum nodeType, + String normalizedName) { + Map<String, Object> properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), normalizedName); + try { + Either<List<SubCategoryData>, TitanOperationStatus> subCategoryEither = titanGenericDao + .getByCriteria(nodeType, properties, SubCategoryData.class); + if (subCategoryEither.isRight() && subCategoryEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get sub-categories, nodeType {}, normalizedName {}, error {}", nodeType, + normalizedName, subCategoryEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List<SubCategoryData> subCategoryList = (subCategoryEither.isLeft() ? subCategoryEither.left().value() + : null); + if (subCategoryList != null && subCategoryList.size() > 0) { + log.debug("Found sub-category for nodeType {} with normalizedName {}", nodeType, normalizedName); + SubCategoryData subCategoryData = subCategoryList.get(0); + SubCategoryDefinition subCategoryDefinition = new SubCategoryDefinition( + subCategoryData.getSubCategoryDataDefinition()); + return Either.left(subCategoryDefinition); + } else { + log.debug("Sub-category for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + normalizedName); + return Either.left(null); + } + } finally { + titanGenericDao.commit(); + } + } + + @Override + public Either<GroupingDefinition, ActionStatus> getGroupingUniqueForType(NodeTypeEnum nodeType, + String groupingNormalizedName) { + Map<String, Object> properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), groupingNormalizedName); + try { + Either<List<GroupingData>, TitanOperationStatus> groupingEither = titanGenericDao.getByCriteria(nodeType, + properties, GroupingData.class); + if (groupingEither.isRight() && groupingEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get grouping, nodeType {}, normalizedName {}, error {}", nodeType, + groupingNormalizedName, groupingEither.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List<GroupingData> groupingList = (groupingEither.isLeft() ? groupingEither.left().value() : null); + if (groupingList != null && groupingList.size() > 0) { + log.debug("Found grouping for nodeType {} with normalizedName {}", nodeType, groupingNormalizedName); + GroupingData groupingData = groupingList.get(0); + GroupingDefinition groupingDefinition = new GroupingDefinition( + groupingData.getGroupingDataDefinition()); + return Either.left(groupingDefinition); + } else { + log.debug("Grouping for nodeType {} with normalizedName {} doesn't exist in graph", nodeType, + groupingNormalizedName); + return Either.left(null); + } + } finally { + titanGenericDao.commit(); + } + } + + /* + * + */ + + @Override + public Either<List<Tag>, ActionStatus> getAllTags() { + try { + Either<List<TagData>, TitanOperationStatus> either = titanGenericDao.getAll(NodeTypeEnum.Tag, + TagData.class); + if (either.isRight()) { + log.debug("Problem while get all tags. reason - {}", either.right().value()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + List<TagData> tagDataList = either.left().value(); + List<Tag> tagList = convertToListOfTag(tagDataList); + return Either.left(tagList); + } finally { + titanGenericDao.commit(); + } + } + + @Override + public <T extends GraphNode> Either<org.openecomp.sdc.be.resources.data.CategoryData, StorageOperationStatus> getCategoryData( + String name, NodeTypeEnum type, Class<T> clazz) { + if (name != null) { + String categoryUid = null; + if (type == NodeTypeEnum.ResourceCategory) { + String[] categoryFields = name.split("/"); + if (categoryFields.length != 2) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + categoryUid = UniqueIdBuilder.buildResourceCategoryUid(categoryFields[0], categoryFields[1], type); + } else { + categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type); + } + Either<T, TitanOperationStatus> either = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(type), + categoryUid, clazz); + + if (either.isRight()) { + TitanOperationStatus titanOperationStatus = either.right().value(); + log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name()); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + return Either.left((org.openecomp.sdc.be.resources.data.CategoryData) either.left().value()); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + private List<Tag> convertToListOfTag(List<TagData> tagDataList) { + List<Tag> tagList = new ArrayList<Tag>(); + for (TagData elem : tagDataList) { + Tag tag = new Tag(); + tag.setName(elem.getName()); + tagList.add(tag); + } + return tagList; + } + + @Override + public Either<List<PropertyScope>, ActionStatus> getAllPropertyScopes() { + // Mock + List<PropertyScope> propertyScopes = new ArrayList<PropertyScope>(); + PropertyScope propertyScope1 = new PropertyScope(); + propertyScope1.setName("A&AI"); + PropertyScope propertyScope2 = new PropertyScope(); + propertyScope2.setName("Order"); + PropertyScope propertyScope3 = new PropertyScope(); + propertyScope3.setName("Runtime"); + propertyScopes.add(propertyScope1); + propertyScopes.add(propertyScope2); + propertyScopes.add(propertyScope3); + return Either.left(propertyScopes); + } + + @Override + public Either<List<ArtifactType>, ActionStatus> getAllArtifactTypes() { + List<ArtifactType> artifactTypes = new ArrayList<ArtifactType>(); + + List<String> artifactTypesList = ConfigurationManager.getConfigurationManager().getConfiguration() + .getArtifactTypes(); + for (String artifactType : artifactTypesList) { + ArtifactType artifactT = new ArtifactType(); + artifactT.setName(artifactType); + artifactTypes.add(artifactT); + } + return Either.left(artifactTypes); + } + + @Override + public Either<Map<String, Object>, ActionStatus> getAllDeploymentArtifactTypes() { + + Map<String, Object> artifactTypes = new HashMap<String, Object>(); + Map<String, DeploymentArtifactTypeConfig> artifactResourceTypes = ConfigurationManager.getConfigurationManager() + .getConfiguration().getResourceDeploymentArtifacts(); + Map<String, DeploymentArtifactTypeConfig> artifactServiceTypes = ConfigurationManager.getConfigurationManager() + .getConfiguration().getServiceDeploymentArtifacts(); + Map<String, DeploymentArtifactTypeConfig> artifactResourceInstanceTypes = ConfigurationManager + .getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + + artifactTypes.put("resourceDeploymentArtifacts", artifactResourceTypes); + artifactTypes.put("serviceDeploymentArtifacts", artifactServiceTypes); + artifactTypes.put("resourceInstanceDeploymentArtifacts", artifactResourceInstanceTypes); + + return Either.left(artifactTypes); + + } + + @Override + public Either<Integer, ActionStatus> getDefaultHeatTimeout() { + return Either.left(ConfigurationManager.getConfigurationManager().getConfiguration() + .getDefaultHeatArtifactTimeoutMinutes()); + } + + @Override + public Either<Map<String, String>, ActionStatus> getResourceTypesMap() { + ResourceTypeEnum[] enumConstants = ResourceTypeEnum.class.getEnumConstants(); + Map<String, String> resourceTypes = new HashMap<String, String>(); + if (enumConstants != null) { + for (int i = 0; i < enumConstants.length; ++i) { + resourceTypes.put(enumConstants[i].name(), enumConstants[i].getValue()); + } + + } + return Either.left(resourceTypes); + } + + @Override + public <T extends GraphNode> Either<CategoryData, StorageOperationStatus> getNewCategoryData(String name, + NodeTypeEnum type, Class<T> clazz) { + if (name != null) { + String categoryUid = UniqueIdBuilder.buildServiceCategoryUid(name, type); + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), name); + Either<List<T>, TitanOperationStatus> either = titanGenericDao.getByCriteria(type, props, clazz); + + if (either.isRight()) { + TitanOperationStatus titanOperationStatus = either.right().value(); + log.debug("Problem while geting category with id {}. reason - {}", categoryUid, titanOperationStatus.name()); + if (titanOperationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + return Either.left((CategoryData) either.left().value().get(0)); + } else { + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java new file mode 100644 index 0000000000..35541e6d46 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java @@ -0,0 +1,234 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("graph-lock-operation") +public class GraphLockOperation implements IGraphLockOperation { + private static Logger log = LoggerFactory.getLogger(ResourceOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + @javax.annotation.Resource + private ICacheMangerOperation cacheManagerOperation; + + public GraphLockOperation() { + super(); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# + * lockResource(java.lang.String, + * org.openecomp.sdc.be.model.operations.api.IResourceOperation) + */ + @Override + public StorageOperationStatus lockComponent(String componentId, NodeTypeEnum nodeType) { + log.info("lock resource with id {}", componentId); + TitanOperationStatus lockElementStatus = null; + try { + + // SET LAST UPDATE DATE OF THE COMPONENT. + // In this way we mark the component as updated one (and component + // won't be fetched from cache since the component in cache has + // different timestamp) + Either<ComponentMetadataData, TitanOperationStatus> updateTime = updateModificationTimeOfComponent( + componentId, nodeType); + if (updateTime.isRight()) { + TitanOperationStatus operationStatus = updateTime.right().value(); + if (operationStatus != TitanOperationStatus.OK) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus); + } + } + + lockElementStatus = titanGenericDao.lockElement(componentId, nodeType); + + } catch (Exception e) { + lockElementStatus = TitanOperationStatus.ALREADY_LOCKED; + + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + + } + + /** + * update the last update date of the component + * + * @param componentId + * @param nodeType + * @return + */ + private Either<ComponentMetadataData, TitanOperationStatus> updateModificationTimeOfComponent(String componentId, + NodeTypeEnum nodeType) { + + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service || nodeType == NodeTypeEnum.Product) { + // We fetch all node since update only timestamp make problems since + // there is default resource type (VFC) which changes component + // resource type when we update only timestamp(ResourceMetadataData + // contains default value VFC on resourceType field). + Either<ComponentMetadataData, TitanOperationStatus> findComp = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(nodeType), componentId, ComponentMetadataData.class); + + if (findComp.isRight()) { + return Either.right(findComp.right().value()); + } + ComponentMetadataData componentMetadataData = findComp.left().value(); + componentMetadataData.getMetadataDataDefinition().setLastUpdateDate(System.currentTimeMillis()); + Either<ComponentMetadataData, TitanOperationStatus> updateNode = titanGenericDao + .updateNode(componentMetadataData, ComponentMetadataData.class); + return updateNode; + } + return Either.right(TitanOperationStatus.OK); + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.impl.IGraphLockOperation# + * unlockResource(java.lang.String, + * org.openecomp.sdc.be.model.operations.api.IResourceOperation) + */ + @Override + public StorageOperationStatus unlockComponent(String componentId, NodeTypeEnum nodeType) { + + Either<Long, StorageOperationStatus> addComponentToCachePart1 = addComponentToCachePart1WithoutCommit( + componentId, nodeType); + + TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(componentId, nodeType); + + if (addComponentToCachePart1.isLeft()) { + Long lastUpdateDate = addComponentToCachePart1.left().value(); + addComponentToCachePart2(componentId, lastUpdateDate, nodeType); + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + } + + private ResourceMetadataData getResourceMetaDataFromResource(Resource resource) { + ResourceMetadataData resourceData = new ResourceMetadataData((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()); + return resourceData; + } + + @Override + public StorageOperationStatus unlockComponentByName(String name, String componentId, NodeTypeEnum nodeType) { + + Either<Long, StorageOperationStatus> addComponentToCachePart1 = addComponentToCachePart1WithoutCommit( + componentId, nodeType); + + TitanOperationStatus lockElementStatus = titanGenericDao.releaseElement(name, nodeType); + + if (addComponentToCachePart1.isLeft()) { + Long lastUpdateDate = addComponentToCachePart1.left().value(); + addComponentToCachePart2(componentId, lastUpdateDate, nodeType); + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + } + + /** + * We fetch the last update date of the component + * + * @param componentId + * @param nodeType + * @return + */ + private Either<Long, StorageOperationStatus> addComponentToCachePart1WithoutCommit(String componentId, + NodeTypeEnum nodeType) { + if (componentId != null) { // In case of error, the componentId might be + // empty. + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service + || nodeType == NodeTypeEnum.Product) { + Long lastUpdateDate = null; + Either<ComponentMetadataData, StorageOperationStatus> resResult = resourceOperation + .getComponentByLabelAndId(componentId, nodeType, ComponentMetadataData.class); + if (resResult.isLeft()) { + ComponentMetadataData resourceMetadataData = resResult.left().value(); + lastUpdateDate = resourceMetadataData.getMetadataDataDefinition().getLastUpdateDate(); + + return Either.left(lastUpdateDate); + } else { + return Either.right(resResult.right().value()); + } + } + } + return Either.right(StorageOperationStatus.OPERATION_NOT_SUPPORTED); + } + + /** + * add the component to the cache + * + * @param componentId + * @param lastUpdateDate + * @param nodeType + * @return + */ + private Either<Long, StorageOperationStatus> addComponentToCachePart2(String componentId, Long lastUpdateDate, + NodeTypeEnum nodeType) { + if (componentId != null) { // In case of error, the componentId might be + // empty. + if (nodeType == NodeTypeEnum.Resource || nodeType == NodeTypeEnum.Service + || nodeType == NodeTypeEnum.Product) { + // add task to Q + log.debug("Going to add component {} of type {} to cache", componentId, nodeType.name().toLowerCase()); + cacheManagerOperation.updateComponentInCache(componentId, lastUpdateDate, nodeType); + } + } + return Either.right(StorageOperationStatus.OPERATION_NOT_SUPPORTED); + } + + @Override + public StorageOperationStatus lockComponentByName(String name, NodeTypeEnum nodeType) { + log.info("lock resource with name {}", name); + TitanOperationStatus lockElementStatus = null; + try { + + lockElementStatus = titanGenericDao.lockElement(name, nodeType); + + } catch (Exception e) { + lockElementStatus = TitanOperationStatus.ALREADY_LOCKED; + + } + + return DaoStatusConverter.convertTitanStatusToStorageStatus(lockElementStatus); + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java new file mode 100644 index 0000000000..9312be45c1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java @@ -0,0 +1,2093 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.GroupData; +import org.openecomp.sdc.be.resources.data.GroupTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("group-operation") +public class GroupOperation extends AbstractOperation implements IGroupOperation { + + private static String ADDING_GROUP = "AddingGroup"; + private static String DELETING_GROUP = "DeletingGroup"; + private static String DELETING_ALL_GROUPS = "DeletingAllGroups"; + private static String ASSOCIATING_GROUP_TO_COMP_INST = "AssociatingGroupToComponentInstance"; + + private static Logger log = LoggerFactory.getLogger(GroupOperation.class.getName()); + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private GroupTypeOperation groupTypeOperation; + + @javax.annotation.Resource + private ApplicationDataTypeCache dataTypeCache; + + @Override + public Either<GroupData, TitanOperationStatus> addGroupToGraph(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition) { + + String groupTypeUid = groupDefinition.getTypeUid(); + + if (groupTypeUid == null) { + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, "Group type id is empty", + ErrorSeverity.ERROR); + return Either.right(TitanOperationStatus.INVALID_ID); + } + + ComponentMetadataData metaData = null; + if (nodeTypeEnum == NodeTypeEnum.Resource) { + metaData = new ResourceMetadataData(); + } else { + metaData = new ServiceMetadataData(); + } + metaData.getMetadataDataDefinition().setUniqueId(componentId); + + groupDefinition.setUniqueId(UniqueIdBuilder.buildGroupUniqueId(componentId, groupDefinition.getName())); + + int propertiesSize = groupDefinition.getProperties() == null ? 0 : groupDefinition.getProperties().size(); + groupDefinition.setPropertyValueCounter(propertiesSize); + + GroupData groupData = new GroupData(groupDefinition); + + TitanOperationStatus status = null; + // Adding group data node to graph + log.debug("Before adding group to graph {}", groupData.toString()); + Either<GroupData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(groupData, + GroupData.class); + log.debug("After adding group to graph {}", groupData.toString()); + if (createNodeResult.isRight()) { + status = createNodeResult.right().value(); + log.error("Failed to add group {} to graph. Status is {}", groupDefinition.getName(), status); + return Either.right(status); + } + + // Associate group to group type + log.debug("Going to associate group {} to its groupType {}", groupDefinition.getName(), groupDefinition.getType()); + Either<GraphRelation, TitanOperationStatus> associateGroupTypeRes = associateGroupToGroupType(groupData, + groupTypeUid); + log.debug("After associating group {} to its groupType {}. Status is {}", groupDefinition.getName(), groupDefinition.getType(), associateGroupTypeRes); + if (associateGroupTypeRes.isRight()) { + status = associateGroupTypeRes.right().value(); + String description = "Failed to associate group " + groupDefinition.getName() + " to its groupType " + + groupDefinition.getType() + " in graph."; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + // Associate group to component RESOURCE/SERVICE/PRODUCT + Either<GraphRelation, TitanOperationStatus> associateComponentRes = associateGroupToComponent(groupData, + nodeTypeEnum, componentId); + if (associateComponentRes.isRight()) { + status = associateComponentRes.right().value(); + String description = "Failed to associate group " + groupDefinition.getName() + " to " + + nodeTypeEnum.getName() + " " + componentId + ". status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + Either<GroupTypeDefinition, TitanOperationStatus> groupTypeRes = groupTypeOperation + .getGroupTypeByUid(groupDefinition.getTypeUid()); + if (groupTypeRes.isRight()) { + TitanOperationStatus operationStatus = groupTypeRes.right().value(); + log.debug("Failed to find group type {}", groupDefinition.getTypeUid()); + if (operationStatus == TitanOperationStatus.NOT_FOUND) { + return Either.right(TitanOperationStatus.INVALID_ID); + } + } + GroupTypeDefinition groupTypeDefinition = groupTypeRes.left().value(); + // 1. find properties from group type + List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties(); + + // 2. check the properties exists in the group type. + // 3. add parent unique id to the properties + // 4. add node per group property which the group point to it and it + // points to the parent unique id + + // Adding properties to group + List<GroupProperty> properties = groupDefinition.getProperties(); + + if (properties != null && false == properties.isEmpty()) { + + if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) { + BeEcompErrorManager.getInstance().logInvalidInputError(ADDING_GROUP, + "group type does not have properties", ErrorSeverity.INFO); + return Either.right(TitanOperationStatus.MATCH_NOT_FOUND); + } + + Map<String, PropertyDefinition> groupTypePropertiesMap = groupTypeProperties.stream() + .collect(Collectors.toMap(p -> p.getName(), p -> p)); + + Either<PropertyValueData, TitanOperationStatus> addPropertyResult = null; + int i = 1; + for (GroupProperty prop : properties) { + addPropertyResult = addPropertyToGroup(groupData, prop, groupTypePropertiesMap.get(prop.getName()), i); + if (addPropertyResult.isRight()) { + status = addPropertyResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + " to property " + + prop.getName() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + i++; + } + } + + // Associate artifacts to group + List<String> artifacts = groupDefinition.getArtifacts(); + + Either<GroupDefinition, TitanOperationStatus> associateArtifactsToGroupOnGraph = associateArtifactsToGroupOnGraph( + groupData.getGroupDataDefinition().getUniqueId(), artifacts); + if (associateArtifactsToGroupOnGraph.isRight() + && associateArtifactsToGroupOnGraph.right().value() != TitanOperationStatus.OK) { + return Either.right(status); + } + /* + * Either<GraphRelation, TitanOperationStatus> addArtifactsRefResult = + * null; if (artifacts != null) { for (String artifactId : artifacts) { + * Either<ArtifactData, TitanOperationStatus> findArtifactRes = + * titanGenericDao .getNode(UniqueIdBuilder + * .getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, + * ArtifactData.class); if (findArtifactRes.isRight()) { status = + * findArtifactRes.right().value(); if (status == + * TitanOperationStatus.NOT_FOUND) { status = + * TitanOperationStatus.INVALID_ID; } String description = + * "Failed to associate group " + groupData.getUniqueId() + + * " to artifact " + artifactId + " in graph. Status is " + status; + * BeEcompErrorManager.getInstance().logInternalFlowError( ADDING_GROUP, + * description, ErrorSeverity.ERROR); return Either.right(status); } + * + * Map<String, Object> props = new HashMap<String, Object>(); + * props.put(GraphPropertiesDictionary.NAME.getProperty(), + * findArtifactRes.left().value().getLabel()); + * + * addArtifactsRefResult = titanGenericDao.createRelation( groupData, + * findArtifactRes.left().value(), GraphEdgeLabels.GROUP_ARTIFACT_REF, + * props); + * + * if (addArtifactsRefResult.isRight()) { status = + * addArtifactsRefResult.right().value(); String description = + * "Failed to associate group " + groupData.getUniqueId() + + * " to artifact " + artifactId + " in graph. Status is " + status; + * BeEcompErrorManager.getInstance().logInternalFlowError( ADDING_GROUP, + * description, ErrorSeverity.ERROR); return Either.right(status); } } } + */ + + // Associate group to members + // map of componentInstances <name: uniqueId> + Map<String, String> members = groupDefinition.getMembers(); + + if (members != null && false == members.isEmpty()) { + Either<GraphRelation, TitanOperationStatus> addMembersRefResult = null; + for (Entry<String, String> member : members.entrySet()) { + if (member.getValue() == null || member.getValue().isEmpty()) { + continue; + } + Either<ComponentInstanceData, TitanOperationStatus> findComponentInstanceRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), member.getValue(), + ComponentInstanceData.class); + if (findComponentInstanceRes.isRight()) { + status = findComponentInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to find to find member of group " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), member.getKey()); + addMembersRefResult = titanGenericDao.createRelation(groupData, findComponentInstanceRes.left().value(), + GraphEdgeLabels.GROUP_MEMBER, props); + + if (addMembersRefResult.isRight()) { + status = addMembersRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + member.getValue() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + } + } + + return Either.left(groupData); + } + + private Either<PropertyValueData, TitanOperationStatus> addPropertyToGroup(GroupData groupData, + GroupProperty groupProperty, PropertyDefinition prop, Integer index) { + + if (prop == null) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + + String propertyId = prop.getUniqueId(); + Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + PropertyData propertyData = findPropertyDefRes.left().value(); + + PropertyDataDefinition propDataDef = propertyData.getPropertyDataDefinition(); + String propertyType = propDataDef.getType(); + String value = groupProperty.getValue(); + + Either<String, TitanOperationStatus> checkInnerType = propertyOperation.checkInnerType(propDataDef); + if (checkInnerType.isRight()) { + TitanOperationStatus status = checkInnerType.right().value(); + return Either.right(status); + } + + String innerType = checkInnerType.left().value(); + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = dataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToGroup", + "Failed to add property to group. Status is " + status, ErrorSeverity.ERROR); + return Either.right(status); + + } + + log.debug("Before validateAndUpdatePropertyValue"); + Either<Object, Boolean> isValid = propertyOperation.validateAndUpdatePropertyValue(propertyType, value, + innerType, allDataTypes.left().value()); + log.debug("After validateAndUpdatePropertyValue. isValid = {}", isValid); + + String newValue = value; + if (isValid.isRight()) { + Boolean res = isValid.right().value(); + if (res == false) { + return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); + } + } else { + Object object = isValid.left().value(); + if (object != null) { + newValue = object.toString(); + } + } + + String uniqueId = UniqueIdBuilder.buildGroupPropertyValueUid((String) groupData.getUniqueId(), index); + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setUniqueId(uniqueId); + propertyValueData.setValue(newValue); + + log.debug("Before adding property value to graph {}",propertyValueData); + Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyValueData, + PropertyValueData.class); + log.debug("After adding property value to graph {}", propertyValueData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + return Either.right(operationStatus); + } + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(propertyValueData, + propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + String description = "Failed to associate property value " + uniqueId + " to property " + propertyId + + " in graph. status is " + operationStatus; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + + createRelResult = titanGenericDao.createRelation(groupData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, + null); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + String description = "Failed to associate group " + groupData.getGroupDataDefinition().getName() + + " to property value " + uniqueId + " in graph. Status is " + operationStatus; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + private Either<GraphRelation, TitanOperationStatus> associateGroupToComponent(GroupData groupData, + NodeTypeEnum nodeTypeEnum, String componentId) { + UniqueIdData componentIdData = new UniqueIdData(nodeTypeEnum, componentId); + + log.debug("Before associating component {} to group {}.", componentId, groupData); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), groupData.getGroupDataDefinition().getName()); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(componentIdData, + groupData, GraphEdgeLabels.GROUP, props); + log.debug("After associating component {} to group {}. Status is {}", componentId, groupData, createRelResult); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.debug("Failed to associate component {} to group {} in graph. Status is {}", componentId, groupData, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createRelResult.left().value()); + } + + private Either<GraphRelation, TitanOperationStatus> associateGroupToGroupType(GroupData groupData, + String groupTypeUid) { + + UniqueIdData groupTypeIdData = new UniqueIdData(NodeTypeEnum.GroupType, groupTypeUid); + + log.debug("Before associating {} to group type {} (uid = {}).", groupData, groupData.getGroupDataDefinition().getType(), groupTypeUid); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(groupData, + groupTypeIdData, GraphEdgeLabels.TYPE_OF, null); + + if (log.isDebugEnabled()) { + log.debug("After associating {} to group type {} (uid = {}). Result is {}", groupData, groupData.getGroupDataDefinition().getType(), groupTypeUid, createRelResult); + } + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + return Either.right(operationStatus); + } + return createRelResult; + } + + @Override + public Either<GroupDefinition, StorageOperationStatus> addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition) { + return addGroup(nodeTypeEnum, componentId, groupDefinition, false); + } + + @Override + public Either<GroupDefinition, StorageOperationStatus> addGroup(NodeTypeEnum nodeTypeEnum, String componentId, + GroupDefinition groupDefinition, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + try { + Either<GroupData, TitanOperationStatus> addGroupRes = addGroupToGraph(nodeTypeEnum, componentId, + groupDefinition); + if (addGroupRes.isRight()) { + TitanOperationStatus status = addGroupRes.right().value(); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + + GroupData groupData = addGroupRes.left().value(); + String groupUid = groupData.getGroupDataDefinition().getUniqueId(); + result = this.getGroup(groupUid, true); + + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph. Failed to add group {} to {}", groupDefinition.getName(), nodeTypeEnum.toString()); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private GroupDefinition convertGroupDataToGroupDefinition(GroupData groupData) { + GroupDefinition newGroupDefinition = new GroupDefinition(groupData.getGroupDataDefinition()); + return newGroupDefinition; + } + + public Either<GroupDefinition, StorageOperationStatus> getGroup(String uniqueId) { + return getGroup(uniqueId, false); + } + + @Override + public Either<GroupDefinition, StorageOperationStatus> getGroup(String uniqueId, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(uniqueId); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + result = Either.left(groupDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<GroupDefinition, TitanOperationStatus> getGroupFromGraph(String uniqueId) { + + return getGroupFromGraph(uniqueId, false, false, false); + + } + + /** + * get the list of artifacts related to a given group + * + * @param groupUniqueId + * @return + */ + // private Either<List<String>, TitanOperationStatus> getGroupArtifacts( + // String groupUniqueId) { + // + // Either<List<String>, TitanOperationStatus> result = null; + // + // Either<List<ImmutablePair<ArtifactData, GraphEdge>>, + // TitanOperationStatus> childrenNodes = titanGenericDao + // .getChildrenNodes( + // UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), + // groupUniqueId, GraphEdgeLabels.GROUP_ARTIFACT_REF, + // NodeTypeEnum.ArtifactRef, ArtifactData.class); + // if (childrenNodes.isRight()) { + // TitanOperationStatus status = childrenNodes.right().value(); + // if (status == TitanOperationStatus.NOT_FOUND) { + // status = TitanOperationStatus.OK; + // } + // result = Either.right(status); + // + // } else { + // + // List<String> artifactsList = new ArrayList<>(); + // List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes + // .left().value(); + // if (list != null) { + // for (ImmutablePair<ArtifactData, GraphEdge> pair : list) { + // ArtifactData artifactData = pair.getKey(); + // String uniqueId = artifactData.getArtifactDataDefinition() + // .getUniqueId(); + // artifactsList.add(uniqueId); + // } + // } + // + // log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList); + // result = Either.left(artifactsList); + // } + // + // return result; + // + // } + + /** + * get members of group + * + * @param groupUniqueId + * @return + */ + protected Either<Map<String, String>, TitanOperationStatus> getGroupMembers(String groupUniqueId) { + + Either<Map<String, String>, TitanOperationStatus> result = null; + + Either<List<ImmutablePair<ComponentInstanceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, + GraphEdgeLabels.GROUP_MEMBER, NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(status); + + } else { + + Map<String, String> compInstaMap = new HashMap<>(); + List<ImmutablePair<ComponentInstanceData, GraphEdge>> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair<ComponentInstanceData, GraphEdge> pair : list) { + ComponentInstanceData componentInstanceData = pair.getKey(); + + String compInstUniqueId = componentInstanceData.getComponentInstDataDefinition().getUniqueId(); + String compInstName = componentInstanceData.getName(); + compInstaMap.put(compInstName, compInstUniqueId); + } + } + + result = Either.left(compInstaMap); + } + + return result; + } + + public Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeOfGroup(String groupUniqueId) { + + Either<ImmutablePair<GroupTypeData, GraphEdge>, TitanOperationStatus> groupTypeRes = titanGenericDao.getChild( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, GraphEdgeLabels.TYPE_OF, + NodeTypeEnum.GroupType, GroupTypeData.class); + + if (groupTypeRes.isRight()) { + TitanOperationStatus status = groupTypeRes.right().value(); + log.debug("Cannot find group type associated with capability {}. Status is {}", groupUniqueId, status); + + BeEcompErrorManager.getInstance().logBeFailedFindAssociationError("Fetch Group type", + NodeTypeEnum.GroupType.getName(), groupUniqueId, String.valueOf(status)); + return Either.right(groupTypeRes.right().value()); + } + + GroupTypeData groupTypeData = groupTypeRes.left().value().getKey(); + + Either<GroupTypeDefinition, TitanOperationStatus> groupTypeByUid = groupTypeOperation + .getGroupTypeByUid(groupTypeData.getGroupTypeDataDefinition().getUniqueId()); + + return groupTypeByUid; + + } + + /** + * get all properties of the group. + * + * the propert definition is taken from the group type. + * + * @param groupUid + * @return + */ + public Either<List<GroupProperty>, TitanOperationStatus> getGroupProperties(String groupUid) { + + List<GroupProperty> groupPropertiesList = new ArrayList<>(); + + Either<GroupTypeDefinition, TitanOperationStatus> groupTypeOfGroupRes = getGroupTypeOfGroup(groupUid); + + if (groupTypeOfGroupRes.isRight()) { + TitanOperationStatus status = groupTypeOfGroupRes.right().value(); + return Either.right(status); + } + + GroupTypeDefinition groupTypeDefinition = groupTypeOfGroupRes.left().value(); + + // Get the properties on the group type of this group + List<PropertyDefinition> groupTypeProperties = groupTypeDefinition.getProperties(); + + if (groupTypeProperties == null || true == groupTypeProperties.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + Map<String, PropertyDefinition> uidToPropDefMap = groupTypeProperties.stream() + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p)); + + // Find all properties values on the group + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUid, + GraphEdgeLabels.PROPERTY_VALUE, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + groupPropertiesList = groupTypeProperties.stream() + .map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList()); + return Either.left(groupPropertiesList); + } else { + return Either.right(status); + } + } + + List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + List<String> processedProps = new ArrayList<>(); + + for (ImmutablePair<PropertyValueData, GraphEdge> propertyValue : list) { + + PropertyValueData propertyValueData = propertyValue.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, + GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = propertyData.getPropertyDataDefinition().getUniqueId(); + + PropertyDefinition propertyDefinition = uidToPropDefMap.get(propertyUniqueId); + GroupProperty groupProperty = new GroupProperty(propertyDefinition, value, propertyValueUid); + + processedProps.add(propertyUniqueId); + + groupPropertiesList.add(groupProperty); + + } + + // Find all properties which does not have property value on the group. + List<GroupProperty> leftProps = groupTypeProperties.stream() + // filter out the group type properties which already processed + .filter(p -> false == processedProps.contains(p.getUniqueId())) + .map(p -> new GroupProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList()); + if (leftProps != null) { + groupPropertiesList.addAll(leftProps); + } + + return Either.left(groupPropertiesList); + } + + public Either<List<GroupDefinition>, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum) { + + return getAllGroupsFromGraph(componentId, componentTypeEnum, false, false, false); + + } + + @Override + public Either<List<GroupDefinition>, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction) { + + Either<List<GroupDefinition>, StorageOperationStatus> result = null; + + try { + + Either<List<GroupDefinition>, TitanOperationStatus> allGroups = this.getAllGroupsFromGraph(componentId, + compTypeEnum); + + if (allGroups.isRight()) { + TitanOperationStatus status = allGroups.right().value(); + log.debug("Failed to retrieve all groups of component {} from graph. Status is {}", componentId, + status); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + List<GroupDefinition> groupsDefinition = allGroups.left().value(); + result = Either.left(groupsDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<GroupDefinition>, StorageOperationStatus> getAllGroups(String componentId, + NodeTypeEnum compTypeEnum) { + return getAllGroups(componentId, compTypeEnum, false); + } + + public Either<GroupData, TitanOperationStatus> deleteGroupFromGraph(String groupUniqueId) { + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupUniqueId); + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + log.debug("Cannot find group {} on graph. Status is {}", groupUniqueId, status); + return Either.right(status); + } + + GroupDefinition groupDefinition = groupFromGraph.left().value(); + // 1. delete all properties values nodes + List<GroupProperty> properties = groupDefinition.getProperties(); + if (properties != null) { + for (GroupProperty groupProperty : properties) { + String propValueUniqueId = groupProperty.getValueUniqueUid(); + + if (propValueUniqueId != null) { + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.PropertyValue, propValueUniqueId); + Either<PropertyValueData, TitanOperationStatus> deleteNode = titanGenericDao + .deleteNode(uniqueIdData, PropertyValueData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + String description = String.format( + "Failed to delete property {} under group {}" + groupUniqueId + + " on graph. Status is {}", + propValueUniqueId, groupDefinition.getName(), status.name()); + log.debug(description); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_GROUP, propValueUniqueId, + status.name()); + return Either.right(status); + } else { + log.trace("Property {} was deleted from geoup {}", propValueUniqueId, groupDefinition.getName()); + } + } + } + } + + // 2. delete the group node + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.Group, groupUniqueId); + Either<GroupData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(uniqueIdData, GroupData.class); + if (deleteNode.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + String description = String.format( + "Failed to delete group {} with uid " + groupUniqueId + " on graph. Status is {}", + groupDefinition.getName(), groupUniqueId, status.name()); + log.debug(description); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_GROUP, groupUniqueId, status.name()); + return Either.right(status); + } else { + log.trace("Group {} was deleted from group", groupUniqueId); + } + + GroupData groupData = deleteNode.left().value(); + return Either.left(groupData); + } + + public Either<GroupDefinition, StorageOperationStatus> deleteGroup(String groupUniqueId) { + return deleteGroup(groupUniqueId, false); + } + + public Either<GroupDefinition, StorageOperationStatus> deleteGroup(String groupUniqueId, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + + Either<GroupData, TitanOperationStatus> deleteGroup = this.deleteGroupFromGraph(groupUniqueId); + + if (deleteGroup.isRight()) { + TitanOperationStatus status = deleteGroup.right().value(); + log.debug("Failed to delete group {} from graph. Status is ", groupUniqueId, status.name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + GroupData groupData = deleteGroup.left().value(); + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + result = Either.left(groupDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<GroupDefinition>, TitanOperationStatus> deleteAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum) { + + Either<List<ImmutablePair<GroupData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, + GraphEdgeLabels.GROUP, NodeTypeEnum.Group, GroupData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logBeFailedFindAllNodesError(DELETING_ALL_GROUPS, + NodeTypeEnum.Group.name(), componentId, status.name()); + } + return Either.right(status); + } + + List<GroupDefinition> result = new ArrayList<>(); + + List<ImmutablePair<GroupData, GraphEdge>> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair<GroupData, GraphEdge> pair : list) { + String uniqueId = pair.left.getGroupDataDefinition().getUniqueId(); + Either<GroupData, TitanOperationStatus> deleteGroupFromGraph = deleteGroupFromGraph(uniqueId); + if (deleteGroupFromGraph.isRight()) { + TitanOperationStatus status = deleteGroupFromGraph.right().value(); + BeEcompErrorManager.getInstance().logBeFailedDeleteNodeError(DELETING_ALL_GROUPS, uniqueId, + status.name()); + return Either.right(status); + } + GroupData groupData = deleteGroupFromGraph.left().value(); + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + result.add(groupDefinition); + } + } + + return Either.left(result); + } + + @Override + public Either<List<GroupDefinition>, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum, boolean inTransaction) { + + Either<List<GroupDefinition>, StorageOperationStatus> result = null; + + try { + + Either<List<GroupDefinition>, TitanOperationStatus> allGroups = this.deleteAllGroupsFromGraph(componentId, + compTypeEnum); + + if (allGroups.isRight()) { + TitanOperationStatus status = allGroups.right().value(); + log.debug("Failed to delete all groups of component {} from graph. Status is {}", componentId, status); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + List<GroupDefinition> groupsDefinition = allGroups.left().value(); + result = Either.left(groupsDefinition); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<GroupDefinition>, StorageOperationStatus> deleteAllGroups(String componentId, + NodeTypeEnum compTypeEnum) { + return deleteAllGroups(componentId, compTypeEnum, false); + } + + public Either<List<GroupDefinition>, StorageOperationStatus> prepareGroupsForCloning( + org.openecomp.sdc.be.model.Component origResource, + ImmutablePair<List<ComponentInstance>, Map<String, String>> cloneInstances) { + + List<GroupDefinition> groupsToCreate = new ArrayList<>(); + Either<List<GroupDefinition>, StorageOperationStatus> result = Either.left(groupsToCreate); + + List<GroupDefinition> groups = origResource.getGroups(); + + if (groups != null) { + // keep typeUid + // keep artifacts uids + // remove properties without valueUniqueId + for (GroupDefinition groupDefinition : groups) { + + GroupDefinition gdToCreate = new GroupDefinition(groupDefinition); + gdToCreate.setUniqueId(null); + gdToCreate.setMembers(null); + + List<GroupProperty> properties = groupDefinition.getProperties(); + if (properties != null) { + // Take properties which was updated in the + // group(getValueUniqueUid != null), + // Then set null instead of the value(prepare for the + // creation). + List<GroupProperty> propertiesToUpdate = properties.stream() + .filter(p -> p.getValueUniqueUid() != null).map(p -> { + p.setValueUniqueUid(null); + return p; + }).collect(Collectors.toList()); + + gdToCreate.setProperties(propertiesToUpdate); + + } + + Map<String, String> members = groupDefinition.getMembers(); + if (cloneInstances != null) { + List<ComponentInstance> createdInstances = cloneInstances.left; + Map<String, String> oldCompUidToNew = cloneInstances.right; + if (members != null && createdInstances != null) { + + Map<String, String> compInstIdToName = createdInstances.stream() + .collect(Collectors.toMap(p -> p.getUniqueId(), p -> p.getName())); + + Map<String, String> membersToCreate = new HashMap<>(); + + for (String oldCompInstId : members.values()) { + String newCompInstUid = oldCompUidToNew.get(oldCompInstId); + if (newCompInstUid == null) { + result = Either.right(StorageOperationStatus.MATCH_NOT_FOUND); + return result; + } + String newCompInstName = compInstIdToName.get(newCompInstUid); + membersToCreate.put(newCompInstName, newCompInstUid); + } + + gdToCreate.setMembers(membersToCreate); + } + } + + log.debug("The group definition for creation is {}", gdToCreate); + + groupsToCreate.add(gdToCreate); + } + + } + + return result; + } + + @Override + public Either<List<GroupDefinition>, StorageOperationStatus> addGroups(NodeTypeEnum nodeTypeEnum, + String componentId, List<GroupDefinition> groups, boolean inTransaction) { + + List<GroupDefinition> createdGroups = new ArrayList<>(); + + Either<List<GroupDefinition>, StorageOperationStatus> result = null; + + try { + + if (groups != null) { + for (GroupDefinition groupDefinition : groups) { + Either<GroupDefinition, StorageOperationStatus> addGroup = this.addGroup(nodeTypeEnum, componentId, + groupDefinition, true); + if (addGroup.isRight()) { + StorageOperationStatus status = addGroup.right().value(); + result = Either.right(status); + return result; + } + + createdGroups.add(addGroup.left().value()); + } + } + + result = Either.left(createdGroups); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + @Override + public Either<List<String>, TitanOperationStatus> getAssociatedGroupsToComponentInstanceFromGraph( + String componentInstanceId) { + + List<String> groups = new ArrayList<>(); + Either<List<String>, TitanOperationStatus> result = Either.left(groups); + + Either<List<ImmutablePair<GroupData, GraphEdge>>, TitanOperationStatus> parentNodes = titanGenericDao + .getParentNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), componentInstanceId, + GraphEdgeLabels.GROUP_MEMBER, NodeTypeEnum.Group, GroupData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus status = parentNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logBeFailedFindParentError("FetchGroupMembers", componentInstanceId, + status.name()); + } + return Either.right(status); + } + + List<ImmutablePair<GroupData, GraphEdge>> fetchedGroups = parentNodes.left().value(); + if (fetchedGroups != null) { + List<String> list = fetchedGroups.stream().map(p -> p.left.getGroupDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + groups.addAll(list); + } + + return result; + + } + + @Override + public Either<List<String>, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId, boolean inTransaction) { + + Either<List<String>, StorageOperationStatus> result = null; + + try { + + Either<List<String>, TitanOperationStatus> groups = this + .getAssociatedGroupsToComponentInstanceFromGraph(componentInstanceId); + + if (groups.isRight()) { + TitanOperationStatus status = groups.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<String> list = groups.left().value(); + + return Either.left(list); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<String>, StorageOperationStatus> getAssociatedGroupsToComponentInstance( + String componentInstanceId) { + return getAssociatedGroupsToComponentInstance(componentInstanceId, false); + } + + @Override + public Either<List<GraphRelation>, TitanOperationStatus> associateGroupsToComponentInstanceOnGraph( + List<String> groups, String componentInstanceId, String compInstName) { + + List<GraphRelation> relations = new ArrayList<>(); + Either<List<GraphRelation>, TitanOperationStatus> result = Either.left(relations); + + if (groups != null && false == groups.isEmpty()) { + + UniqueIdData compInstData = new UniqueIdData(NodeTypeEnum.ResourceInstance, componentInstanceId); + + for (String groupId : groups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), compInstName); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(groupData, + compInstData, GraphEdgeLabels.GROUP_MEMBER, props); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + compInstName + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_GROUP_TO_COMP_INST, description, + ErrorSeverity.ERROR); + result = Either.right(status); + break; + } + GraphRelation graphRelation = createRelation.left().value(); + relations.add(graphRelation); + } + } else { + result = Either.right(TitanOperationStatus.OK); + } + + return result; + } + + public StorageOperationStatus associateGroupsToComponentInstance(List<String> groups, String componentInstanceId, + String compInstName) { + + return associateGroupsToComponentInstance(groups, componentInstanceId, compInstName, false); + } + + @Override + public StorageOperationStatus associateGroupsToComponentInstance(List<String> groups, String componentInstanceId, + String compInstName, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + Either<List<GraphRelation>, TitanOperationStatus> either = this + .associateGroupsToComponentInstanceOnGraph(groups, componentInstanceId, compInstName); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<GraphRelation>, TitanOperationStatus> dissociateAllGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String artifactId) { + + List<GraphRelation> relations = new ArrayList<>(); + Either<List<GraphRelation>, TitanOperationStatus> result = Either.left(relations); + + Either<List<GroupDefinition>, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, + componentTypeEnum, true, true, false); + if (allGroupsFromGraph.isRight()) { + TitanOperationStatus status = allGroupsFromGraph.right().value(); + return Either.right(status); + } + + List<GroupDefinition> allGroups = allGroupsFromGraph.left().value(); + if (allGroups == null || allGroups.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + // Find all groups which contains this artifact id + List<GroupDefinition> associatedGroups = allGroups.stream() + .filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(artifactId)) + .collect(Collectors.toList()); + + if (associatedGroups != null && false == associatedGroups.isEmpty()) { + log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), artifactId); + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId); + for (GroupDefinition groupDefinition : associatedGroups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + relations.add(deleteRelation.left().value()); + } + + return result; + + } else { + log.debug("No group under component id {} is associated to artifact {}", componentId, artifactId); + return Either.right(TitanOperationStatus.OK); + } + + } + + public Either<GroupDefinition, TitanOperationStatus> getGroupFromGraph(String uniqueId, boolean skipProperties, + boolean skipMembers, boolean skipArtifacts) { + + Either<GroupDefinition, TitanOperationStatus> result = null; + + Either<GroupData, TitanOperationStatus> groupRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), uniqueId, GroupData.class); + if (groupRes.isRight()) { + TitanOperationStatus status = groupRes.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, + String.valueOf(status)); + result = Either.right(status); + return result; + } + + GroupData groupData = groupRes.left().value(); + + GroupDefinition groupDefinition = convertGroupDataToGroupDefinition(groupData); + + Either<GroupTypeDefinition, TitanOperationStatus> groupTypeOfGroup = getGroupTypeOfGroup(uniqueId); + + if (groupTypeOfGroup.isRight()) { + TitanOperationStatus status = groupTypeOfGroup.right().value(); + log.debug("Failed to retrieve capability type of capability {}. Status is {}", uniqueId, status); + + result = Either.right(status); + return result; + } + + GroupTypeDefinition groupTypeDefinition = groupTypeOfGroup.left().value(); + + groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId()); + + if (false == skipMembers) { + Either<Map<String, String>, TitanOperationStatus> membersRes = getGroupMembers(uniqueId); + if (membersRes.isRight()) { + TitanOperationStatus status = membersRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + Map<String, String> members = membersRes.left().value(); + groupDefinition.setMembers(members); + } + } + + if (false == skipProperties) { + Either<List<GroupProperty>, TitanOperationStatus> propertiesRes = getGroupProperties(uniqueId); + if (propertiesRes.isRight()) { + TitanOperationStatus status = propertiesRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + List<GroupProperty> properties = propertiesRes.left().value(); + groupDefinition.setProperties(properties); + } + } + + if (false == skipArtifacts) { + Either<List<ImmutablePair<String, String>>, TitanOperationStatus> artifactsRes = getGroupArtifactsPairs( + uniqueId); + if (artifactsRes.isRight()) { + TitanOperationStatus status = artifactsRes.right().value(); + if (status != TitanOperationStatus.OK) { + result = Either.right(status); + return result; + } + } else { + List<String> artifactsUid = new ArrayList<>(); + List<String> artifactsUUID = new ArrayList<>(); + + List<ImmutablePair<String, String>> list = artifactsRes.left().value(); + if (list != null) { + for (ImmutablePair<String, String> pair : list) { + String uid = pair.left; + String UUID = pair.right; + artifactsUid.add(uid); + artifactsUUID.add(UUID); + } + groupDefinition.setArtifacts(artifactsUid); + groupDefinition.setArtifactsUuid(artifactsUUID); + } + } + } + result = Either.left(groupDefinition); + + return result; + + } + + @Override + public boolean isGroupExist(String groupName, boolean inTransaction) { + + Either<List<GroupData>, TitanOperationStatus> eitherGroup = null; + try { + Map<String, Object> properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NAME.getProperty(), groupName); + + eitherGroup = titanGenericDao.getByCriteria(NodeTypeEnum.Group, properties, GroupData.class); + return eitherGroup.isLeft() && !eitherGroup.left().value().isEmpty(); + + } finally { + handleTransactionCommitRollback(inTransaction, eitherGroup); + } + } + + protected Either<List<GroupDefinition>, TitanOperationStatus> getAllGroupsFromGraph(String componentId, + NodeTypeEnum componentTypeEnum, boolean skipProperties, boolean skipMembers, boolean skipArtifacts) { + + List<GroupDefinition> groups = new ArrayList<GroupDefinition>(); + + Either<List<ImmutablePair<GroupData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(componentTypeEnum), componentId, + GraphEdgeLabels.GROUP, NodeTypeEnum.Group, GroupData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<GroupData, GraphEdge>> graphGroups = childrenNodes.left().value(); + + if (graphGroups == null || true == graphGroups.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + // Consumer<String> consumer = (x) -> getGroup(x); + // StreamUtils.takeWhile(graphGroups.stream().map(p -> + // p.left.getUniqueId()), consumer); + + for (ImmutablePair<GroupData, GraphEdge> pair : graphGroups) { + + String groupUniqueId = pair.left.getGroupDataDefinition().getUniqueId(); + Either<GroupDefinition, TitanOperationStatus> groupRes = this.getGroupFromGraph(groupUniqueId, + skipProperties, skipMembers, skipArtifacts); + + if (groupRes.isRight()) { + TitanOperationStatus status = groupRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } else { + groups.add(groupRes.left().value()); + } + + } + + return Either.left(groups); + } + + @Override + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + Either<List<GraphRelation>, TitanOperationStatus> either = this + .dissociateAllGroupsFromArtifactOnGraph(componentId, componentTypeEnum, artifactId); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus dissociateAllGroupsFromArtifact(String componentId, NodeTypeEnum componentTypeEnum, + String artifactId) { + + return dissociateAllGroupsFromArtifact(componentId, componentTypeEnum, artifactId, false); + } + + @Override + public TitanOperationStatus dissociateAndAssociateGroupsFromArtifactOnGraph(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) { + + Either<List<GroupDefinition>, TitanOperationStatus> allGroupsFromGraph = getAllGroupsFromGraph(componentId, + componentTypeEnum, true, true, false); + if (allGroupsFromGraph.isRight()) { + TitanOperationStatus status = allGroupsFromGraph.right().value(); + return status; + } + + List<GroupDefinition> allGroups = allGroupsFromGraph.left().value(); + if (allGroups == null || allGroups.isEmpty()) { + return TitanOperationStatus.OK; + } + + // Find all groups which contains this artifact id + List<GroupDefinition> associatedGroups = allGroups.stream() + .filter(p -> p.getArtifacts() != null && p.getArtifacts().contains(oldArtifactId)) + .collect(Collectors.toList()); + + if (associatedGroups != null && false == associatedGroups.isEmpty()) { + + log.debug("The groups {} contains the artifact {}", associatedGroups.stream().map(p -> p.getName()).collect(Collectors.toList()), oldArtifactId); + + UniqueIdData oldArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, oldArtifactId); + UniqueIdData newArtifactData = new UniqueIdData(NodeTypeEnum.ArtifactRef, + newArtifact.getArtifactDataDefinition().getUniqueId()); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), newArtifactData.getLabel()); + + for (GroupDefinition groupDefinition : associatedGroups) { + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupDefinition.getUniqueId()); + + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, + oldArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + log.trace("After dissociate group {} from artifac {}", groupDefinition.getName(), oldArtifactId); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(groupData, + newArtifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF, props); + log.trace("After associate group {} to artifact {}", groupDefinition.getName(), newArtifact.getUniqueIdKey()); + if (createRelation.isRight()) { + TitanOperationStatus status = createRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return status; + } + } + + } + return TitanOperationStatus.OK; + } + + @Override + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact, boolean inTransaction) { + + StorageOperationStatus result = null; + + try { + TitanOperationStatus status = this.dissociateAndAssociateGroupsFromArtifactOnGraph(componentId, + componentTypeEnum, oldArtifactId, newArtifact); + + if (status != TitanOperationStatus.OK && status != TitanOperationStatus.NOT_FOUND) { + result = DaoStatusConverter.convertTitanStatusToStorageStatus(status); + return result; + } + + result = StorageOperationStatus.OK; + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result != StorageOperationStatus.OK) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus dissociateAndAssociateGroupsFromArtifact(String componentId, + NodeTypeEnum componentTypeEnum, String oldArtifactId, ArtifactData newArtifact) { + return dissociateAndAssociateGroupsFromArtifact(componentId, componentTypeEnum, oldArtifactId, newArtifact, + false); + } + + private Either<List<ImmutablePair<String, String>>, TitanOperationStatus> getGroupArtifactsPairs( + String groupUniqueId) { + + Either<List<ImmutablePair<String, String>>, TitanOperationStatus> result = null; + + Either<List<ImmutablePair<ArtifactData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Group), groupUniqueId, + GraphEdgeLabels.GROUP_ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class); + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + result = Either.right(status); + + } else { + + List<ImmutablePair<String, String>> artifactsList = new ArrayList<>(); + List<ImmutablePair<ArtifactData, GraphEdge>> list = childrenNodes.left().value(); + if (list != null) { + for (ImmutablePair<ArtifactData, GraphEdge> pair : list) { + ArtifactData artifactData = pair.getKey(); + String uniqueId = artifactData.getArtifactDataDefinition().getUniqueId(); + String UUID = artifactData.getArtifactDataDefinition().getArtifactUUID(); + ImmutablePair<String, String> artifact = new ImmutablePair<String, String>(uniqueId, UUID); + artifactsList.add(artifact); + } + } + + log.debug("The artifacts list related to group {} is {}", groupUniqueId, artifactsList); + result = Either.left(artifactsList); + } + + return result; + + } + + public Either<List<GroupDefinition>, TitanOperationStatus> updateGroupVersionOnGraph(List<String> groupsUniqueId) { + + if (groupsUniqueId != null) { + + List<GroupDefinition> groups = new ArrayList<>(); + for (String groupUid : groupsUniqueId) { + Either<GroupDefinition, TitanOperationStatus> either = updateGroupVersionOnGraph(groupUid); + if (either.isRight()) { + log.debug("Failed to update version of group {}", groupUid); + return Either.right(either.right().value()); + } + groups.add(either.left().value()); + } + return Either.left(groups); + } + + return Either.right(TitanOperationStatus.OK); + + } + + /** + * update the group version of a given group. It also creates a new UUID. + * + * @param groupUniqueId + * @return + */ + public Either<GroupDefinition, TitanOperationStatus> updateGroupVersionOnGraph(String groupUniqueId) { + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupUniqueId, false, + false, false); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + return Either.right(status); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + String version = groupDefinition.getVersion(); + String newVersion = increaseMajorVersion(version); + Integer pvCounter = groupDefinition.getPropertyValueCounter(); + + GroupData groupData = new GroupData(); + groupData.getGroupDataDefinition().setUniqueId(groupUniqueId); + groupData.getGroupDataDefinition().setVersion(newVersion); + groupData.getGroupDataDefinition().setPropertyValueCounter(pvCounter); + + String groupUUID = UniqueIdBuilder.generateUUID(); + groupData.getGroupDataDefinition().setGroupUUID(groupUUID); + + Either<GroupData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(groupData, GroupData.class); + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + groupFromGraph = this.getGroupFromGraph(groupUniqueId, false, false, false); + return groupFromGraph; + } + + } + } + + /** + * The version of the group is an integer. In order to support BC, we might + * get a version in a float format. + * + * @param version + * @return + */ + private String increaseMajorVersion(String version) { + + String[] versionParts = version.split(LifecycleOperation.VERSION_DELIMETER_REGEXP); + Integer majorVersion = Integer.parseInt(versionParts[0]); + + majorVersion++; + + return String.valueOf(majorVersion); + + } + + public Either<GroupDefinition, TitanOperationStatus> associateArtifactsToGroupOnGraph(String groupId, + List<String> artifactsId) { + + if (artifactsId == null || artifactsId.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + for (String artifactId : artifactsId) { + Either<ArtifactData, TitanOperationStatus> findArtifactRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if (findArtifactRes.isRight()) { + TitanOperationStatus status = findArtifactRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to associate group " + groupId + " to artifact " + artifactId + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), findArtifactRes.left().value().getLabel()); + + GraphNode groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + Either<GraphRelation, TitanOperationStatus> addArtifactsRefResult = titanGenericDao.createRelation( + groupData, findArtifactRes.left().value(), GraphEdgeLabels.GROUP_ARTIFACT_REF, props); + + if (addArtifactsRefResult.isRight()) { + TitanOperationStatus status = addArtifactsRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + " to artifact " + + artifactId + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + } + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + } + + public Either<GroupDefinition, TitanOperationStatus> associateMembersToGroupOnGraph(String groupId, + Map<String, String> members) { + + if (members != null && false == members.isEmpty()) { + Either<GraphRelation, TitanOperationStatus> addMembersRefResult = null; + for (Entry<String, String> member : members.entrySet()) { + Either<ComponentInstanceData, TitanOperationStatus> findComponentInstanceRes = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), member.getValue(), + ComponentInstanceData.class); + if (findComponentInstanceRes.isRight()) { + + TitanOperationStatus status = findComponentInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to find to find component instance group " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), member.getKey()); + GraphNode groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + addMembersRefResult = titanGenericDao.createRelation(groupData, findComponentInstanceRes.left().value(), + GraphEdgeLabels.GROUP_MEMBER, props); + if (addMembersRefResult.isRight()) { + TitanOperationStatus status = addMembersRefResult.right().value(); + String description = "Failed to associate group " + groupData.getUniqueId() + + " to component instance " + member.getValue() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, + ErrorSeverity.ERROR); + return Either.right(status); + } + } + } + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupId, true, false, + true); + + return groupFromGraph; + } + + public Either<GroupDefinition, TitanOperationStatus> dissociateArtifactsFromGroupOnGraph(String groupId, + List<String> artifactsId) { + + if (artifactsId == null || artifactsId.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + for (String artifactId : artifactsId) { + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.Group, artifactId); + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_ARTIFACT_REF); + log.trace("After dissociate group {} from artifact {}", groupId, artifactId); + + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to diassociate group " + groupId + " from artifact " + artifactId + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + } + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + + } + + public Either<GroupDefinition, TitanOperationStatus> dissociateMembersFromGroupOnGraph(String groupId, + Map<String, String> members) { + + if (members == null || members.isEmpty()) { + return Either.right(TitanOperationStatus.OK); + } + + UniqueIdData groupData = new UniqueIdData(NodeTypeEnum.Group, groupId); + for (Entry<String, String> member : members.entrySet()) { + + UniqueIdData artifactData = new UniqueIdData(NodeTypeEnum.Group, member.getValue()); + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(groupData, + artifactData, GraphEdgeLabels.GROUP_MEMBER); + log.trace("After dissociate group {} from members", groupId, member.getValue()); + + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + String description = "Failed to diassociate group " + groupId + " from member " + member.getValue() + + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ADDING_GROUP, description, ErrorSeverity.ERROR); + return Either.right(status); + } + + } + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(groupId, true, true, + false); + + return groupFromGraph; + + } + + /** + * dissociate artifacts from a group. It do not delete the artifacts !!! + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either<GroupDefinition, StorageOperationStatus> dissociateArtifactsFromGroup(String groupId, + List<String> artifactsId, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + Either<GroupDefinition, TitanOperationStatus> titanRes = this.dissociateArtifactsFromGroupOnGraph(groupId, + artifactsId); + + if (titanRes.isRight()) { + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(storageOperationStatus); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<GroupDefinition, StorageOperationStatus> dissociateMembersFromGroup(String groupId, + Map<String, String> members, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + Either<GroupDefinition, TitanOperationStatus> titanRes = this.dissociateMembersFromGroupOnGraph(groupId, + members); + + if (titanRes.isRight()) { + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(storageOperationStatus); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Associate artifacts to a given group + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either<GroupDefinition, StorageOperationStatus> associateArtifactsToGroup(String groupId, + List<String> artifactsId, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + + Either<GroupDefinition, TitanOperationStatus> titanRes = this.associateArtifactsToGroupOnGraph(groupId, + artifactsId); + + if (titanRes.isRight()) { + StorageOperationStatus status = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(status); + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Associate artifacts to a given group + * + * @param groupId + * @param artifactsId + * @param inTransaction + * @return + */ + public Either<GroupDefinition, StorageOperationStatus> associateMembersToGroup(String groupId, + Map<String, String> members, boolean inTransaction) { + + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + + Either<GroupDefinition, TitanOperationStatus> titanRes = this.associateMembersToGroupOnGraph(groupId, + members); + + if (titanRes.isRight()) { + StorageOperationStatus status = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanRes.right().value()); + result = Either.right(status); + return result; + } + + result = Either.left(titanRes.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<List<GroupDefinition>, StorageOperationStatus> updateGroupVersion(List<String> groupsId, + boolean inTransaction) { + + Either<List<GroupDefinition>, StorageOperationStatus> result = null; + + try { + Either<List<GroupDefinition>, TitanOperationStatus> updateGroupVersionOnGraph = this + .updateGroupVersionOnGraph(groupsId); + + if (updateGroupVersionOnGraph.isRight()) { + result = Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(updateGroupVersionOnGraph.right().value())); + return result; + } + + result = Either.left(updateGroupVersionOnGraph.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<GroupDefinition, StorageOperationStatus> updateGroupName(String uniqueId, String newName, + boolean inTransaction) { + Either<GroupDefinition, StorageOperationStatus> result = null; + + try { + Either<GroupDefinition, TitanOperationStatus> updateGroupNameOnGraph = this.updateGroupNameOnGraph(uniqueId, + newName); + + if (updateGroupNameOnGraph.isRight()) { + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(updateGroupNameOnGraph.right().value())); + return result; + } + + result = Either.left(updateGroupNameOnGraph.left().value()); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + BeEcompErrorManager.getInstance().logBeExecuteRollbackError("Rollback on graph"); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private Either<GroupDefinition, TitanOperationStatus> updateGroupNameOnGraph(String uniqueId, String newName) { + + Either<GroupDefinition, TitanOperationStatus> groupFromGraph = this.getGroupFromGraph(uniqueId, false, false, + false); + + if (groupFromGraph.isRight()) { + TitanOperationStatus status = groupFromGraph.right().value(); + return Either.right(status); + } else { + GroupDefinition groupDefinition = groupFromGraph.left().value(); + String version = groupDefinition.getVersion(); + String newVersion = increaseMajorVersion(version); + Integer pvCounter = groupDefinition.getPropertyValueCounter(); + + GroupData groupData = new GroupData(); + groupData.getGroupDataDefinition().setUniqueId(uniqueId); + groupData.getGroupDataDefinition().setVersion(newVersion); + groupData.getGroupDataDefinition().setName(newName); + groupData.getGroupDataDefinition().setPropertyValueCounter(pvCounter); + + Either<GroupData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(groupData, GroupData.class); + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + groupFromGraph = this.getGroupFromGraph(uniqueId, false, false, false); + return groupFromGraph; + } + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java new file mode 100644 index 0000000000..4251e503e6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java @@ -0,0 +1,385 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.GroupTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.GroupTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("group-type-operation") +public class GroupTypeOperation extends AbstractOperation implements IGroupTypeOperation { + + String CREATE_FLOW_CONTEXT = "CreateGroupType"; + String GET_FLOW_CONTEXT = "GetGroupType"; + + @Resource + private PropertyOperation propertyOperation; + + public GroupTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(GroupTypeOperation.class.getName()); + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition) { + + return addGroupType(groupTypeDefinition, false); + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> addGroupType(GroupTypeDefinition groupTypeDefinition, + boolean inTransaction) { + + Either<GroupTypeDefinition, StorageOperationStatus> result = null; + + try { + + Either<GroupTypeData, TitanOperationStatus> eitherStatus = addGroupTypeToGraph(groupTypeDefinition); + + if (eitherStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, + groupTypeDefinition.getType(), eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + + } else { + GroupTypeData groupTypeData = eitherStatus.left().value(); + + String uniqueId = groupTypeData.getUniqueId(); + Either<GroupTypeDefinition, StorageOperationStatus> groupTypeRes = this.getGroupType(uniqueId, true); + + if (groupTypeRes.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, + groupTypeDefinition.getType(), eitherStatus.right().value().name()); + } + + result = groupTypeRes; + + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + public Either<GroupTypeDefinition, TitanOperationStatus> getGroupTypeByUid(String uniqueId) { + + Either<GroupTypeDefinition, TitanOperationStatus> result = null; + + Either<GroupTypeData, TitanOperationStatus> groupTypesRes = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.GroupType), uniqueId, GroupTypeData.class); + + if (groupTypesRes.isRight()) { + TitanOperationStatus status = groupTypesRes.right().value(); + log.debug("Group type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + GroupTypeData gtData = groupTypesRes.left().value(); + GroupTypeDefinition groupTypeDefinition = new GroupTypeDefinition(gtData.getGroupTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, + properList -> groupTypeDefinition.setProperties(properList)); + + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability type {}", uniqueId); + return Either.right(propertiesStatus); + } + + result = Either.left(groupTypeDefinition); + + return result; + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId) { + + return getGroupType(uniqueId, false); + + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupType(String uniqueId, boolean inTransaction) { + Function<String, Either<GroupTypeDefinition, TitanOperationStatus>> groupTypeGetter = uId -> getGroupTypeByUid( + uId); + return getElementType(groupTypeGetter, uniqueId, inTransaction); + + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type) { + return getLatestGroupTypeByType(type, false); + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getLatestGroupTypeByType(String type, + boolean inTransaction) { + Map<String, Object> mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + + } + + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByCriteria(String type, + Map<String, Object> properties, boolean inTransaction) { + Either<GroupTypeDefinition, StorageOperationStatus> result = null; + try { + if (type == null || type.isEmpty()) { + log.error("type is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Either<List<GroupTypeData>, TitanOperationStatus> groupTypeEither = titanGenericDao + .getByCriteria(NodeTypeEnum.GroupType, properties, GroupTypeData.class); + if (groupTypeEither.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(groupTypeEither.right().value())); + } else { + GroupTypeDataDefinition dataDefinition = groupTypeEither.left().value().stream() + .map(e -> e.getGroupTypeDataDefinition()).findFirst().get(); + result = getGroupType(dataDefinition.getUniqueId(), inTransaction); + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, + String version) { + return getGroupTypeByTypeAndVersion(type, version, false); + } + + @Override + public Either<GroupTypeDefinition, StorageOperationStatus> getGroupTypeByTypeAndVersion(String type, String version, + boolean inTransaction) { + Map<String, Object> mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + + return getGroupTypeByCriteria(type, mapCriteria, inTransaction); + } + + /** + * + * Add group type to graph. + * + * 1. Add group type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per + * property & if exists) + * + * @param groupTypeDefinition + * @return + */ + private Either<GroupTypeData, TitanOperationStatus> addGroupTypeToGraph(GroupTypeDefinition groupTypeDefinition) { + + log.debug("Got group type {}", groupTypeDefinition); + + String ctUniqueId = UniqueIdBuilder.buildGroupTypeUid(groupTypeDefinition.getType(), + groupTypeDefinition.getVersion()); + // capabilityTypeDefinition.setUniqueId(ctUniqueId); + + GroupTypeData groupTypeData = buildGroupTypeData(groupTypeDefinition, ctUniqueId); + + log.debug("Before adding group type to graph. groupTypeData = {}", groupTypeData); + + Either<GroupTypeData, TitanOperationStatus> createGTResult = titanGenericDao.createNode(groupTypeData, + GroupTypeData.class); + log.debug("After adding group type to graph. status is = {}", createGTResult); + + if (createGTResult.isRight()) { + TitanOperationStatus operationStatus = createGTResult.right().value(); + log.error("Failed to add group type {} to graph. Status is {}", groupTypeDefinition.getType(), operationStatus); + return Either.right(operationStatus); + } + + GroupTypeData resultCTD = createGTResult.left().value(); + List<PropertyDefinition> properties = groupTypeDefinition.getProperties(); + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToCapablityType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.GroupType, properties); + if (addPropertiesToCapablityType.isRight()) { + log.error("Failed add properties {} to capability {}", properties, groupTypeDefinition.getType()); + return Either.right(addPropertiesToCapablityType.right().value()); + } + + String derivedFrom = groupTypeDefinition.getDerivedFrom(); + if (derivedFrom != null) { + + // TODO: Need to find the parent. need to take the latest one since + // we may have many versions of the same type + /* + * log.debug("Before creating relation between group type {} to its parent {}", ctUniqueId, derivedFrom); UniqueIdData from + * = new UniqueIdData(NodeTypeEnum.CapabilityType, ctUniqueId); + * UniqueIdData to = new UniqueIdData(NodeTypeEnum.CapabilityType, + * derivedFrom); Either<GraphRelation, TitanOperationStatus> + * createRelation = titanGenericDao .createRelation(from, to, + * GraphEdgeLabels.DERIVED_FROM, null); + * log.debug("After create relation between capability type {} to its parent {}. Status is {}", ctUniqueId, derivedFrom, if (createRelation.isRight()) { return + * Either.right(createRelation.right().value()); } + * + */ + } + + return Either.left(createGTResult.left().value()); + + } + + /** + * + * convert between graph Node object to Java object + * + * @param capabilityTypeData + * @return + */ + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is {}", capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + private GroupTypeData buildGroupTypeData(GroupTypeDefinition groupTypeDefinition, String ctUniqueId) { + + GroupTypeData groupTypeData = new GroupTypeData(groupTypeDefinition); + + groupTypeData.getGroupTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = groupTypeData.getGroupTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + groupTypeData.getGroupTypeDataDefinition().setCreationTime(creationDate); + groupTypeData.getGroupTypeDataDefinition().setModificationTime(creationDate); + + return groupTypeData; + } + + public Either<Boolean, StorageOperationStatus> isCapabilityTypeDerivedFrom(String childCandidateType, + String parentCandidateType) { + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childCandidateType); + Either<List<CapabilityTypeData>, TitanOperationStatus> getResponse = titanGenericDao + .getByCriteria(NodeTypeEnum.CapabilityType, propertiesToMatch, CapabilityTypeData.class); + if (getResponse.isRight()) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch capability type {}, error: {}", childCandidateType, titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } + String childUniqueId = getResponse.left().value().get(0).getUniqueId(); + Set<String> travelledTypes = new HashSet<>(); + do { + travelledTypes.add(childUniqueId); + Either<List<ImmutablePair<CapabilityTypeData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityType), childUniqueId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + TitanOperationStatus titanOperationStatus = getResponse.right().value(); + log.debug("Couldn't fetch derived from node for capability type {}, error: {}", childCandidateType, + titanOperationStatus); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanOperationStatus)); + } else { + log.debug("Derived from node is not found for type {} - this is OK for root capability."); + return Either.left(false); + } + } + String derivedFromUniqueId = childrenNodes.left().value().get(0).getLeft().getUniqueId(); + if (derivedFromUniqueId.equals(parentCandidateType)) { + log.debug("Verified that capability type {} derives from capability type {}", childCandidateType, + parentCandidateType); + return Either.left(true); + } + childUniqueId = derivedFromUniqueId; + } while (!travelledTypes.contains(childUniqueId)); + // this stop condition should never be used, if we use it, we have an + // illegal cycle in graph - "derived from" hierarchy cannot be cycled. + // It's here just to avoid infinite loop in case we have such cycle. + log.error("Detected a cycle of \"derived from\" edges starting at capability type node {}", childUniqueId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + /** + * FOR TEST ONLY + * + * @param propertyOperation + */ + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + @Override + public Either<GroupTypeData, TitanOperationStatus> getLatestGroupTypeByNameFromGraph(String name) { + + return null; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java new file mode 100644 index 0000000000..5d7b8c5991 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java @@ -0,0 +1,492 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.HeatParameterData; +import org.openecomp.sdc.be.resources.data.HeatParameterValueData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; + +import fj.data.Either; + +@Component("heat-parameter-operation") +public class HeatParametersOperation implements IHeatParametersOperation { + + public static final String EMPTY_VALUE = null; + + private static Logger log = LoggerFactory.getLogger(HeatParametersOperation.class.getName()); + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + private Gson gson = new Gson(); + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public StorageOperationStatus getHeatParametersOfNode(NodeTypeEnum nodeType, String uniqueId, List<HeatParameterDefinition> properties) { + + Either<List<ImmutablePair<HeatParameterData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.HEAT_PARAMETER, NodeTypeEnum.HeatParameter, + HeatParameterData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + List<ImmutablePair<HeatParameterData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<HeatParameterData, GraphEdge> immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (log.isDebugEnabled()) + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + HeatParameterData propertyData = immutablePair.getKey(); + HeatParameterDefinition propertyDefinition = convertParameterDataToParameterDefinition(propertyData, propertyName, uniqueId); + + properties.add(propertyDefinition); + + if (log.isTraceEnabled()) { + log.trace("getHeatParametersOfNode - property {} associated to node {}", propertyDefinition, uniqueId); + } + } + + } + + return StorageOperationStatus.OK; + } + + public StorageOperationStatus getParametersValueNodes(NodeTypeEnum parentNodeType, String parentUniqueId, List<HeatParameterValueData> heatValues) { + + Either<List<ImmutablePair<HeatParameterValueData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(parentNodeType), parentUniqueId, GraphEdgeLabels.PARAMETER_VALUE, + NodeTypeEnum.HeatParameterValue, HeatParameterValueData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + List<ImmutablePair<HeatParameterValueData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<HeatParameterValueData, GraphEdge> immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + log.trace("Heat value " + propertyName + " is associated to node " + parentUniqueId); + HeatParameterValueData propertyData = immutablePair.getKey(); + + heatValues.add(propertyData); + } + + } + + return StorageOperationStatus.OK; + } + + @Override + public Either<List<HeatParameterDefinition>, StorageOperationStatus> deleteAllHeatParametersAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + List<HeatParameterDefinition> heatParams = new ArrayList<HeatParameterDefinition>(); + StorageOperationStatus propertiesOfNodeRes = getHeatParametersOfNode(nodeType, uniqueId, heatParams); + + if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) { + return Either.right(propertiesOfNodeRes); + } + + for (HeatParameterDefinition propertyDefinition : heatParams) { + + String propertyUid = propertyDefinition.getUniqueId(); + Either<HeatParameterData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete heat parameter with id {}", propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + log.debug("The heat parameters deleted from node {} are {}", uniqueId, heatParams); + return Either.left(heatParams); + } + + @Override + public StorageOperationStatus deleteAllHeatValuesAssociatedToNode(NodeTypeEnum parentNodeType, String parentUniqueId) { + + List<HeatParameterValueData> heatValues = new ArrayList<HeatParameterValueData>(); + StorageOperationStatus propertiesOfNodeRes = getParametersValueNodes(parentNodeType, parentUniqueId, heatValues); + + if (!propertiesOfNodeRes.equals(StorageOperationStatus.OK) && !propertiesOfNodeRes.equals(StorageOperationStatus.NOT_FOUND)) { + return propertiesOfNodeRes; + } + + for (HeatParameterValueData propertyDefinition : heatValues) { + + String propertyUid = (String) propertyDefinition.getUniqueId(); + Either<HeatParameterValueData, TitanOperationStatus> deletePropertyRes = deleteHeatParameterValueFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete heat parameter value with id {}", propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + + } + + log.debug("The heat values deleted from node {} are {}", parentUniqueId, heatValues); + return StorageOperationStatus.OK; + } + + private Either<HeatParameterData, TitanOperationStatus> deleteHeatParameterFromGraph(String propertyId) { + log.debug("Before deleting heat parameter from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameter), propertyId, HeatParameterData.class); + } + + private Either<HeatParameterValueData, TitanOperationStatus> deleteHeatParameterValueFromGraph(String propertyId) { + log.debug("Before deleting heat parameter from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.HeatParameterValue), propertyId, HeatParameterValueData.class); + } + + @Override + public StorageOperationStatus addPropertiesToGraph(List<HeatParameterDefinition> properties, String parentId, NodeTypeEnum nodeType) { + + if (properties != null) { + for (HeatParameterDefinition propertyDefinition : properties) { + + String propertyName = propertyDefinition.getName(); + + // type and value should be validated in business logic: + // ArtifactsBusinessLogic.validateAndConvertHeatParamers(ArtifactDefinition) + + // StorageOperationStatus validateAndUpdateProperty = + // validateAndUpdateProperty(propertyDefinition); + // if (validateAndUpdateProperty != StorageOperationStatus.OK) { + // log.error("Property " + propertyDefinition + " is invalid. + // Status is " + validateAndUpdateProperty); + // return StorageOperationStatus.BAD_REQUEST; + // } + + Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, parentId, nodeType); + + if (addPropertyToGraph.isRight()) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value()); + } + } + } + + return StorageOperationStatus.OK; + + } + + @Override + public StorageOperationStatus updateHeatParameters(List<HeatParameterDefinition> properties) { + + if (properties == null) { + return StorageOperationStatus.OK; + } + for (HeatParameterDefinition property : properties) { + + HeatParameterData heatParameterData = new HeatParameterData(property); + Either<HeatParameterData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterData, HeatParameterData.class); + if (updateNode.isRight()) { + log.debug("failed to update heat parameter in graph. id = {}", property.getUniqueId()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value()); + } + } + + return StorageOperationStatus.OK; + } + + public Either<HeatParameterData, TitanOperationStatus> addPropertyToGraph(String propertyName, HeatParameterDefinition propertyDefinition, String parentId, NodeTypeEnum nodeType) { + + UniqueIdData parentNode = new UniqueIdData(nodeType, parentId); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildHeatParameterUniqueId(parentId, propertyName)); + HeatParameterData propertyData = new HeatParameterData(propertyDefinition); + + log.debug("Before adding property to graph {}", propertyData); + Either<HeatParameterData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, HeatParameterData.class); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(parentNode, propertyData, GraphEdgeLabels.HEAT_PARAMETER, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + + if (log.isDebugEnabled()) { + log.error("Failed to associate {} {} to heat parameter {} in graph. Status is {}", nodeType.getName(), parentId, propertyName, operationStatus); + } + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public StorageOperationStatus validateAndUpdateProperty(HeatParameterDefinition propertyDefinition) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + HeatParameterType type = getType(propertyType); + + if (type == null) { + log.info("The type {} of heat is invalid", type); + + return StorageOperationStatus.INVALID_TYPE; + } + propertyDefinition.setType(type.getType()); + + log.trace("After validating property type {}", propertyType); + + // validate default value + String defaultValue = propertyDefinition.getDefaultValue(); + boolean isValidProperty = isValidValue(type, defaultValue); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", defaultValue, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(defaultValue)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(defaultValue)) { + String convertedValue = converter.convert(defaultValue, null, null); + propertyDefinition.setDefaultValue(convertedValue); + } + + // validate current value + String value = propertyDefinition.getCurrentValue(); + isValidProperty = isValidValue(type, value); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + if (isEmptyValue(value)) { + log.debug("Value was not sent for property {}. Set value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setCurrentValue(EMPTY_VALUE); + } else if (!value.equals("")) { + String convertedValue = converter.convert(value, null, null); + propertyDefinition.setCurrentValue(convertedValue); + } + + return StorageOperationStatus.OK; + } + + public HeatParameterDefinition convertParameterDataToParameterDefinition(HeatParameterData propertyDataResult, String propertyName, String resourceId) { + log.debug("convert to HeatParamereDefinition {}", propertyDataResult); + + HeatParameterDefinition propertyDefResult = new HeatParameterDefinition(propertyDataResult.getHeatDataDefinition()); + + propertyDefResult.setName(propertyName); + + return propertyDefResult; + } + + private HeatParameterType getType(String propertyType) { + + HeatParameterType type = HeatParameterType.isValidType(propertyType); + + return type; + + } + + protected boolean isValidValue(HeatParameterType type, String value) { + if (isEmptyValue(value)) { + return true; + } + + PropertyTypeValidator validator = type.getValidator(); + + boolean isValid = validator.isValid(value, null, null); + if (true == isValid) { + return true; + } else { + return false; + } + + } + + public boolean isEmptyValue(String value) { + if (value == null) { + return true; + } + return false; + } + + public boolean isNullParam(String value) { + if (value == null) { + return true; + } + return false; + } + + @Override + public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) { + String heatEnvId = UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParam.getName()); + Either<HeatParameterValueData, TitanOperationStatus> getNode = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), heatEnvId, HeatParameterValueData.class); + if (getNode.isRight() || getNode.left().value() == null) { + if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) { + log.debug("Updated heat parameter value equals default value. No need to create heat parameter value for heat parameter {}", heatParam.getUniqueId()); + return Either.left(null); + } + return createHeatParameterValue(heatParam, artifactId, resourceInstanceId, artifactLabel); + } else { + heatParam.setUniqueId(heatEnvId); + return updateHeatParameterValue(heatParam); + } + } + + public Either<HeatParameterValueData, StorageOperationStatus> updateHeatParameterValue(HeatParameterDefinition heatParam) { + HeatParameterValueData heatParameterValue = new HeatParameterValueData(); + heatParameterValue.setUniqueId(heatParam.getUniqueId()); + if (heatParam.getCurrentValue() == null || (heatParam.getDefaultValue() != null && heatParam.getCurrentValue().equals(heatParam.getDefaultValue()))) { + Either<GraphRelation, TitanOperationStatus> deleteParameterValueIncomingRelation = titanGenericDao.deleteIncomingRelationByCriteria(heatParameterValue, GraphEdgeLabels.PARAMETER_VALUE, null); + if (deleteParameterValueIncomingRelation.isRight()) { + log.debug("Failed to delete heat parameter value incoming relation on graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteParameterValueIncomingRelation.right().value())); + } + Either<Edge, TitanOperationStatus> getOutgoingRelation = titanGenericDao.getOutgoingEdgeByCriteria(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), (String) heatParameterValue.getUniqueId(), GraphEdgeLabels.PARAMETER_IMPL, null); + if (getOutgoingRelation.isRight()) { + log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getOutgoingRelation.right().value())); + } + Edge edge = getOutgoingRelation.left().value(); + if (edge == null) { + log.debug("Failed to get heat parameter value outgoing relation from graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + edge.remove(); + + Either<HeatParameterValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(heatParameterValue, HeatParameterValueData.class); + if (deleteNode.isRight()) { + log.debug("Failed to delete heat parameter value on graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value())); + } + return Either.left(deleteNode.left().value()); + } + heatParameterValue.setValue(heatParam.getCurrentValue()); + Either<HeatParameterValueData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(heatParameterValue, HeatParameterValueData.class); + if (updateNode.isRight()) { + log.debug("Failed to update heat parameter value in graph. id = {}", heatParameterValue.getUniqueId()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + } + return Either.left(updateNode.left().value()); + } + + public Either<HeatParameterValueData, StorageOperationStatus> createHeatParameterValue(HeatParameterDefinition heatParam, String artifactId, String resourceInstanceId, String artifactLabel) { + + Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph = addHeatValueToGraph(heatParam, artifactLabel, artifactId, resourceInstanceId); + if (addHeatValueToGraph.isRight()) { + log.debug("Failed to create heat parameters value on graph for artifact {}", artifactId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addHeatValueToGraph.right().value())); + } + return Either.left(addHeatValueToGraph.left().value()); + } + + public Either<HeatParameterValueData, TitanOperationStatus> addHeatValueToGraph(HeatParameterDefinition heatParameter, String artifactLabel, String artifactId, String resourceInstanceId) { + + UniqueIdData heatEnvNode = new UniqueIdData(NodeTypeEnum.ArtifactRef, artifactId); + HeatParameterValueData heatValueData = new HeatParameterValueData(); + heatValueData.setUniqueId(UniqueIdBuilder.buildHeatParameterValueUniqueId(resourceInstanceId, artifactLabel, heatParameter.getName())); + heatValueData.setValue(heatParameter.getCurrentValue()); + + log.debug("Before adding property to graph {}", heatValueData); + Either<HeatParameterValueData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(heatValueData, HeatParameterValueData.class); + log.debug("After adding property to graph {}", heatValueData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add heat value {} to graph. Status is {}", heatValueData.getUniqueId(), operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), heatParameter.getName()); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(heatEnvNode, heatValueData, GraphEdgeLabels.PARAMETER_VALUE, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate heat value {} to heat env artifact {} in graph. Status is {}", heatValueData.getUniqueId(), artifactId, operationStatus); + return Either.right(operationStatus); + } + UniqueIdData heatParameterNode = new UniqueIdData(NodeTypeEnum.HeatParameter, heatParameter.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> createRel2Result = titanGenericDao.createRelation(heatValueData, heatParameterNode, GraphEdgeLabels.PARAMETER_IMPL, null); + if (createRel2Result.isRight()) { + TitanOperationStatus operationStatus = createRel2Result.right().value(); + log.error("Failed to associate heat value {} to heat parameter {} in graph. Status is {}", heatValueData.getUniqueId(), heatParameter.getName(), operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java new file mode 100644 index 0000000000..e2d13a9cff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java @@ -0,0 +1,1184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.process.traversal.Order; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.json.simple.JSONObject; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GetInputValueInfo; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.operations.api.IInputsOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.InputsData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import com.thinkaurelius.titan.core.TitanVertexQuery; +import com.thinkaurelius.titan.core.attribute.Cmp; + +import fj.data.Either; + +@Component("input-operation") +public class InputsOperation extends AbstractOperation implements IInputsOperation { + + private static String ASSOCIATING_INPUT_TO_PROP = "AssociatingInputToComponentInstanceProperty"; + + private static Logger log = LoggerFactory.getLogger(InputsOperation.class.getName()); + + @Autowired + private ComponentInstanceOperation componentInstanceOperation; + Gson gson = new Gson(); + + /** + * Delete specific input from component Although inputId is unique, pass also componentId as all other methods, and also check that the inputId is inside that componentId. + */ + @Override + public Either<String, StorageOperationStatus> deleteInput(String inputId) { + log.debug(String.format("Before deleting input: %s from graph", inputId)); + Either<List<ComponentInstanceInput>, TitanOperationStatus> inputsValueStatus = this.getComponentInstanceInputsByInputId(inputId); + if(inputsValueStatus.isLeft()){ + List<ComponentInstanceInput> inputsValueLis = inputsValueStatus.left().value(); + if(!inputsValueLis.isEmpty()){ + for(ComponentInstanceInput inputValue: inputsValueLis){ + Either<InputValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), inputValue.getValueUniqueUid(), InputValueData.class); + if (deleteNode.isRight()) { + StorageOperationStatus convertTitanStatusToStorageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()); + return Either.right(convertTitanStatusToStorageStatus); + } + } + } + } + Either<InputsData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), inputId, InputsData.class); + if (deleteNode.isRight()) { + StorageOperationStatus convertTitanStatusToStorageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNode.right().value()); + return Either.right(convertTitanStatusToStorageStatus); + } else { + return Either.left(inputId); + } + } + + @Override + public Either<List<InputDefinition>, TitanOperationStatus> addInputsToGraph(String componentId, NodeTypeEnum nodeType, Map<String, InputDefinition> inputs, Map<String, DataTypeDefinition> dataTypes) { + + List<InputDefinition> newInputs = new ArrayList<InputDefinition>(); + if (inputs != null) { + for (Entry<String, InputDefinition> entry : inputs.entrySet()) { + + String inputName = entry.getKey(); + InputDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property " + propertyDefinition + " is invalid. Status is " + validateAndUpdateProperty); + return Either.right(TitanOperationStatus.INVALID_PROPERTY); + } + + Either<InputsData, TitanOperationStatus> addPropertyToGraph = addInputToGraph(inputName, propertyDefinition, componentId, nodeType); + + if (addPropertyToGraph.isRight()) { + return Either.right(addPropertyToGraph.right().value()); + } + InputDefinition createdInputyDefinition = convertInputDataToInputDefinition(addPropertyToGraph.left().value()); + createdInputyDefinition.setName(inputName); + createdInputyDefinition.setParentUniqueId(componentId); + newInputs.add(createdInputyDefinition); + } + } + + return Either.left(newInputs); + } + + @Override + public TitanOperationStatus addInputsToGraph(TitanVertex metadata, String componentId, Map<String, InputDefinition> inputs, Map<String, DataTypeDefinition> dataTypes) { + + if (inputs != null) { + for (Entry<String, InputDefinition> entry : inputs.entrySet()) { + + String inputName = entry.getKey(); + InputDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {} ", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.INVALID_PROPERTY; + } + + TitanOperationStatus addPropertyToGraph = addInputToGraph(metadata, inputName, propertyDefinition, componentId); + + if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) { + return addPropertyToGraph; + } + + } + } + + return TitanOperationStatus.OK; + } + + @Override + public Either<List<InputDefinition>, StorageOperationStatus> getInputsOfComponent(String compId, String fromName, int amount) { + List<InputDefinition> inputs = new ArrayList<>(); + if ((fromName == null || fromName.isEmpty()) && amount == 0) { + + TitanOperationStatus status = findAllResourceInputs(compId, inputs); + + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource {}. status is {}", compId, status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } else { + + Either<TitanGraph, TitanOperationStatus> graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphRes.right().value())); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), compId).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.INVALID_ID)); + } + + TitanVertex rootVertex = vertices.iterator().next(); + TitanVertexQuery<?> query; + if (fromName == null || fromName.isEmpty()) + query = rootVertex.query().direction(Direction.OUT).labels(GraphEdgeLabels.INPUT.getProperty()).orderBy(GraphEdgePropertiesDictionary.NAME.getProperty(), Order.incr).limit(amount); + else + query = rootVertex.query().direction(Direction.OUT).labels(GraphEdgeLabels.INPUT.getProperty()).orderBy(GraphEdgePropertiesDictionary.NAME.getProperty(), Order.incr).has(GraphEdgePropertiesDictionary.NAME.getProperty(), Cmp.GREATER_THAN, fromName).limit(amount); + + Iterable<TitanEdge> edgesCreatorEges = query.edges(); + + if (edgesCreatorEges == null) { + log.debug("No edges in graph for criteria"); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND)); + } + Iterator<TitanEdge> edgesCreatorIterator = edgesCreatorEges.iterator(); + + if (edgesCreatorIterator != null) { + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + GraphEdge graphEdge = null; + + Map<String, Object> edgeProps = titanGenericDao.getProperties(edge); + GraphEdgeLabels edgeTypeFromGraph = GraphEdgeLabels.getByName(edge.label()); + graphEdge = new GraphEdge(edgeTypeFromGraph, edgeProps); + + Vertex outgoingVertex = edge.inVertex(); + Map<String, Object> properties = titanGenericDao.getProperties(outgoingVertex); + InputsData data = GraphElementFactory.createElement(NodeTypeEnum.Input.getName(), GraphElementTypeEnum.Node, properties, InputsData.class); + String inputName = (String) graphEdge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + InputDefinition inputDefinition = this.convertInputDataToInputDefinition(data); + inputDefinition.setName(inputName); + inputDefinition.setParentUniqueId(compId); + + inputs.add(inputDefinition); + + } + } + + } + if (true == inputs.isEmpty()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(TitanOperationStatus.NOT_FOUND)); + } + + return Either.left(inputs); + + } + + @Override + public Either<Map<String, InputDefinition>, StorageOperationStatus> deleteAllInputsAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + Wrapper<TitanOperationStatus> errorWrapper; + List<InputDefinition> inputs = new ArrayList<>(); + TitanOperationStatus findAllResourceAttribues = this.findNodeNonInheretedInputs(uniqueId, inputs); + errorWrapper = (findAllResourceAttribues != TitanOperationStatus.OK) ? new Wrapper<>(findAllResourceAttribues) : new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + for (InputDefinition inDef : inputs) { + log.debug("Before deleting inputs from graph {}", inDef.getUniqueId()); + Either<InputsData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), inDef.getUniqueId(), InputsData.class); + if (deleteNode.isRight()) { + errorWrapper.setInnerElement(deleteNode.right().value()); + break; + } + } + } + + if (errorWrapper.isEmpty()) { + Map<String, InputDefinition> inputsMap = inputs.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + return Either.left(inputsMap); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(errorWrapper.getInnerElement())); + } + + } + + @Override + public Either<InputsData, StorageOperationStatus> addInput(String inputName, InputDefinition inputDefinition, String resourceId, NodeTypeEnum nodeType) { + + ComponentMetadataData componentMetadata = null; + + Either<InputsData, TitanOperationStatus> either = addInputToGraph(inputName, inputDefinition, resourceId, nodeType); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + @Override + public Either<AttributeData, StorageOperationStatus> updateInput(String inputId, InputDefinition newInDef, Map<String, DataTypeDefinition> dataTypes) { + // TODO Auto-generated method stub + return null; + } + + public Either<InputsData, TitanOperationStatus> addInputToGraph(String propertyName, InputDefinition inputDefinition, String componentId, NodeTypeEnum nodeType) { + + UniqueIdData from = new UniqueIdData(nodeType, componentId); + + List<PropertyConstraint> constraints = inputDefinition.getConstraints(); + + inputDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, propertyName)); + InputsData inputData = new InputsData(inputDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", inputData); + Either<InputsData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(inputData, InputsData.class); + log.debug("After adding input to graph {}", inputData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add input {} to graph. status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), propertyName); + + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(from, inputData, GraphEdgeLabels.INPUT, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. status is {}", componentId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addInputToGraph(TitanVertex vertex, String propertyName, InputDefinition inputDefinition, String componentId) { + + List<PropertyConstraint> constraints = inputDefinition.getConstraints(); + + inputDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(componentId, propertyName)); + InputsData inputData = new InputsData(inputDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", inputData); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(inputData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add input {} to graph. status is {}", propertyName, operationStatus); + return operationStatus; + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), propertyName); + TitanVertex inputVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(vertex, inputVertex, GraphEdgeLabels.INPUT, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + TitanOperationStatus operationStatus = createRelResult; + log.error("Failed to associate resource {} to property {} in graph. status is {}", componentId, propertyName, operationStatus); + return operationStatus; + } + + return createRelResult; + + } + + public InputDefinition convertInputDataToInputDefinition(InputsData inputDataResult) { + if (log.isDebugEnabled()) + log.debug("The object returned after create property is {}", inputDataResult); + + InputDefinition propertyDefResult = new InputDefinition(inputDataResult.getPropertyDataDefinition()); + propertyDefResult.setConstraints(convertConstraints(inputDataResult.getConstraints())); + + return propertyDefResult; + } + + public boolean isInputExist(List<InputDefinition> inputs, String resourceUid, String inputName) { + + if (inputs == null) { + return false; + } + + for (InputDefinition propertyDefinition : inputs) { + String parentUniqueId = propertyDefinition.getParentUniqueId(); + String name = propertyDefinition.getName(); + + if (parentUniqueId.equals(resourceUid) && name.equals(inputName)) { + return true; + } + } + + return false; + + } + + @Override + public TitanOperationStatus findAllResourceInputs(String uniqueId, List<InputDefinition> inputs) { + // final NodeElementFetcher<InputDefinition> singleNodeFetcher = + // (resourceIdParam, attributesParam) -> + // findNodeNonInheretedInputs(resourceIdParam, componentType, + // attributesParam); + // return findAllResourceElementsDefinitionRecursively(uniqueId, inputs, + // singleNodeFetcher); + return findNodeNonInheretedInputs(uniqueId, inputs); + } + + @Override + public TitanOperationStatus findNodeNonInheretedInputs(String uniqueId, List<InputDefinition> inputs) { + Either<List<ImmutablePair<InputsData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.INPUT, NodeTypeEnum.Input, InputsData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List<ImmutablePair<InputsData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<InputsData, GraphEdge> immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String inputName = (String) edge.getProperties().get(GraphEdgePropertiesDictionary.NAME.getProperty()); + log.debug("Input {} is associated to node {}", inputName, uniqueId); + InputsData inputData = immutablePair.getKey(); + InputDefinition inputDefinition = this.convertInputDataToInputDefinition(inputData); + + inputDefinition.setName(inputName); + inputDefinition.setParentUniqueId(uniqueId); + + inputs.add(inputDefinition); + + log.trace("findInputsOfNode - input {} associated to node {}", inputDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + public Either<InputDefinition, StorageOperationStatus> getInputById(String uniqueId, boolean skipProperties, boolean skipInputsvalue) { + Either<InputDefinition, TitanOperationStatus> status = getInputFromGraph(uniqueId, skipProperties, skipInputsvalue); + + if (status.isRight()) { + log.error("Failed to get input {} from graph {}. status is {}", uniqueId, status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + public <ElementDefinition> TitanOperationStatus findAllResourceElementsDefinitionRecursively(String resourceId, List<ElementDefinition> elements, NodeElementFetcher<ElementDefinition> singleNodeFetcher) { + + log.trace("Going to fetch elements under resource {}", resourceId); + TitanOperationStatus resourceAttributesStatus = singleNodeFetcher.findAllNodeElements(resourceId, elements); + + if (resourceAttributesStatus != TitanOperationStatus.OK) { + return resourceAttributesStatus; + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus != TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find parent elements of resource " + resourceId + ". status is " + parentNodesStatus, ErrorSeverity.ERROR); + return parentNodesStatus; + } + } + + if (parentNodes.isLeft()) { + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllResourceElementsDefinitionRecursively(parentUniqueId, elements, singleNodeFetcher); + + if (addParentIntStatus != TitanOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("findAllResourceElementsDefinitionRecursively", "Failed to find all resource elements of resource " + parentUniqueId, ErrorSeverity.ERROR); + + return addParentIntStatus; + } + } + return TitanOperationStatus.OK; + } + + public TitanOperationStatus associatePropertyToInput(String riId, String inputId, InputValueData property, String name) { + TitanOperationStatus status = TitanOperationStatus.OK; + Either<TitanGraph, TitanOperationStatus> graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return graphRes.right().value(); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), property.getUniqueId()).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return TitanOperationStatus.INVALID_ID; + } + // Either<PropertyData, TitanOperationStatus> findPropertyDefRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), + // propertyId, PropertyData.class); + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), name); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), riId); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, inputId); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, property.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + status = addPropRefResult.right().value(); + String description = "Failed to associate input " + inputData.getUniqueId() + " to property " + property.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return status; + } + return status; + + } + + public TitanOperationStatus associatePropertyToInput(String riId, String inputId, ComponentInstanceProperty property, GetInputValueInfo getInput) { + TitanOperationStatus status = TitanOperationStatus.OK; + Either<TitanGraph, TitanOperationStatus> graphRes = titanGenericDao.getGraph(); + if (graphRes.isRight()) { + log.error("Failed to retrieve graph. status is {}", graphRes); + return graphRes.right().value(); + } + + TitanGraph titanGraph = graphRes.left().value(); + @SuppressWarnings("unchecked") + Iterable<TitanVertex> vertices = titanGraph.query().has(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), property.getUniqueId()).vertices(); + if (vertices == null || false == vertices.iterator().hasNext()) { + return TitanOperationStatus.INVALID_ID; + } + // Either<PropertyData, TitanOperationStatus> findPropertyDefRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), + // propertyId, PropertyData.class); + + Map<String, Object> props = new HashMap<String, Object>(); + if(getInput!=null){ + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), getInput.getPropName()); + if (getInput.isList()) { + String index = getInput.getIndexValue().toString(); + if (getInput.getGetInputIndex() != null) { + index = getInput.getGetInputIndex().getInputName(); + + } + props.put(GraphEdgePropertiesDictionary.GET_INPUT_INDEX.getProperty(), index); + } + } + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), riId); + + GraphNode inputData = new UniqueIdData(NodeTypeEnum.Input, inputId); + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.PropertyValue, property.getValueUniqueUid()); + Either<GraphRelation, TitanOperationStatus> addPropRefResult = titanGenericDao.createRelation(inputData, propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + status = addPropRefResult.right().value(); + String description = "Failed to associate input " + inputData.getUniqueId() + " to property " + property.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return status; + } + return status; + + } + + private Either<InputDefinition, TitanOperationStatus> getInputFromGraph(String uniqueId, boolean skipProperties, boolean skipInputsValue) { + + Either<InputDefinition, TitanOperationStatus> result = null; + + Either<InputsData, TitanOperationStatus> inputRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), uniqueId, InputsData.class); + if (inputRes.isRight()) { + TitanOperationStatus status = inputRes.right().value(); + log.debug("Failed to retrieve group {} from graph. Status is {}", uniqueId, status); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("Fetch Group", uniqueId, String.valueOf(status)); + result = Either.right(status); + return result; + } + + InputsData inputData = inputRes.left().value(); + + InputDefinition groupDefinition = this.convertInputDataToInputDefinition(inputData); + + if (false == skipInputsValue) { + List<ComponentInstanceInput> propsList = new ArrayList<ComponentInstanceInput>(); + + Either<List<ImmutablePair<InputValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Input), uniqueId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.InputValue, InputValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + return Either.right(status); + } + + } + if(propertyImplNodes.isLeft()){ + List<ImmutablePair<InputValueData, GraphEdge>> propertyDataPairList = propertyImplNodes.left().value(); + for (ImmutablePair<InputValueData, GraphEdge> propertyValue : propertyDataPairList) { + + InputValueData propertyValueData = propertyValue.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + String propertyUniqueId = (String) propertyDefPair.left.getUniqueId(); + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueUid); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + + propsList.add(resourceInstanceProperty); + + } + + groupDefinition.setInputsValue(propsList); + } + + } + + if (false == skipProperties) { + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List<ComponentInstanceProperty> propsRresult = new ArrayList<>(); + for (ImmutablePair<PropertyValueData, GraphEdge> propertyValueDataPair : list) { + PropertyValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + return Either.right(status); + } + + } + if(propertyDefRes.isLeft()){ + + ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setName((String) propertyValueDataPair.right.getProperties().get(GraphPropertiesDictionary.NAME.getProperty())); + + propsRresult.add(resourceInstanceProperty); + } + + groupDefinition.setProperties(propsRresult); + } + + } + + result = Either.left(groupDefinition); + + return result; + + } + + public ImmutablePair<TitanOperationStatus, String> findInputValue(String resourceInstanceId, String propertyId) { + + log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId); + + Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllRes = getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceId); + if (getAllRes.isRight()) { + TitanOperationStatus status = getAllRes.right().value(); + log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status); + return new ImmutablePair<TitanOperationStatus, String>(status, null); + } + + List<ComponentInstanceInput> list = getAllRes.left().value(); + if (list != null) { + for (ComponentInstanceInput instanceProperty : list) { + String propertyUniqueId = instanceProperty.getUniqueId(); + String valueUniqueUid = instanceProperty.getValueUniqueUid(); + log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid); + if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) { + log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId); + return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid); + } + } + } + + return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null); + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid) { + + return getAllInputsOfResourceInstanceOnlyInputDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance); + + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either<List<ComponentInstanceInput>, StorageOperationStatus> getComponentInstanceInputsByInputId(String resourceInstanceUid, String inputId) { + + Either<List<ComponentInstanceInput>, TitanOperationStatus> status = getComponentInstanceInputsByInputId(inputId); + if (status.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either<List<ComponentInstanceProperty>, StorageOperationStatus> getComponentInstancePropertiesByInputId(String resourceInstanceUid, String inputId) { + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> status = getComponentInstancePropertiesByInputId(inputId); + if (status.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } + + return Either.left(status.left().value()); + + } + + public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstanceOnlyInputDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) { + + Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either<List<ImmutablePair<InputValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.INPUT_VALUE, NodeTypeEnum.InputValue, InputValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<InputValueData, GraphEdge>> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List<ComponentInstanceInput> result = new ArrayList<>(); + + + for (ImmutablePair<InputValueData, GraphEdge> propertyValueDataPair : list) { + + InputValueData propertyValueData = propertyValueDataPair.getLeft(); + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either<ImmutablePair<InputsData, GraphEdge>, TitanOperationStatus> inputNodes = titanGenericDao.getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), propertyValueData.getUniqueId(), GraphEdgeLabels.GET_INPUT, NodeTypeEnum.Input, InputsData.class); + + if (inputNodes.isRight()) { + + return Either.right(inputNodes.right().value()); + } + + InputsData input = inputNodes.left().value().left; + String inputId = input.getPropertyDataDefinition().getUniqueId(); + + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + Either<Edge, TitanOperationStatus> inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null); + if (inputsEges.isRight()) { + TitanOperationStatus status = inputsEges.right().value(); + + return Either.right(status); + } + Edge edge = inputsEges.left().value(); + String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid); + + //resourceInstanceProperty.setName(inputName); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setName(inputName); + resourceInstanceProperty.setParentUniqueId(inputId); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + //resourceInstanceProperty.setComponentInstanceName(componentInsName); + resourceInstanceProperty.setComponentInstanceId(resourceInstanceUid); + + result.add(resourceInstanceProperty); + } + + + return Either.left(result); + } + + public Either<List<ComponentInstanceInput>, TitanOperationStatus> getComponentInstanceInputsByInputId(String inputId) { + + Either<InputsData, TitanOperationStatus> findResInputRes = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, InputsData.class); + + if (findResInputRes.isRight()) { + TitanOperationStatus status = findResInputRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + + + // Either<List<InputValueData>, TitanOperationStatus> propertyImplNodes + // = titanGenericDao.getByCriteria(NodeTypeEnum.InputValue, props, + // InputValueData.class); + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId); + + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource input for id = {}", inputId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + + return Either.right(status); + } + TitanVertex vertex = vertexService.left().value(); + + Either<List<ImmutablePair<InputValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.InputValue, InputValueData.class); + + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<InputValueData, GraphEdge>> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List<ComponentInstanceInput> result = new ArrayList<>(); + for (ImmutablePair<InputValueData, GraphEdge> propertyValueDataPair : list) { + InputValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + // Either<List<Edge>, TitanOperationStatus> out = + // titanGenericDao.getEdgesForNode(propertyValueData, + // Direction.OUT); + // Either<List<Edge>, TitanOperationStatus> in = + // titanGenericDao.getEdgesForNode(propertyValueData, Direction.IN); + Either<Edge, TitanOperationStatus> inputsvalueEges = titanGenericDao.getIncomingEdgeByCriteria(propertyValueData, GraphEdgeLabels.INPUT_VALUE, null); + if (inputsvalueEges.isRight()) { + TitanOperationStatus status = inputsvalueEges.right().value(); + + return Either.right(status); + } + Edge edge = inputsvalueEges.left().value(); + String componentInsName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + String componentInsId = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.OWNER_ID.getProperty()); + + Either<ImmutablePair<InputsData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InputValue), propertyValueUid, GraphEdgeLabels.INPUT_IMPL, NodeTypeEnum.Input, InputsData.class); + + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair<InputsData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + + InputsData propertyData = propertyDefPair.left; + + Either<Edge, TitanOperationStatus> inputsEges = titanGenericDao.getIncomingEdgeByCriteria(propertyData, GraphEdgeLabels.INPUT, null); + if (inputsEges.isRight()) { + TitanOperationStatus status = inputsEges.right().value(); + + return Either.right(status); + } + edge = inputsEges.left().value(); + String inputName = (String) titanGenericDao.getProperty(edge, GraphEdgePropertiesDictionary.NAME.getProperty()); + + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceInput resourceInstanceProperty = new ComponentInstanceInput(propertyData.getPropertyDataDefinition(), inputId, value, propertyValueUid); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + resourceInstanceProperty.setName(inputName); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + // resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setComponentInstanceName(componentInsName); + resourceInstanceProperty.setComponentInstanceId(componentInsId); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + + } + + public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getComponentInstancePropertiesByInputId(String inputId) { + + Either<InputsData, TitanOperationStatus> findResInputRes = titanGenericDao.getNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, InputsData.class); + + if (findResInputRes.isRight()) { + TitanOperationStatus status = findResInputRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + //Map<String, Object> props = new HashMap<String, Object>(); + //props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), resourceInstanceUid); + + // Either<List<PropertyValueData>, TitanOperationStatus> + // propertyImplNodes = + // titanGenericDao.getByCriteria(NodeTypeEnum.PropertyValue, props, + // PropertyValueData.class); + Either<TitanVertex, TitanOperationStatus> vertexService = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId); + + if (vertexService.isRight()) { + log.debug("failed to fetch vertex of resource input for id = {}", inputId); + TitanOperationStatus status = vertexService.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + + return Either.right(status); + } + TitanVertex vertex = vertexService.left().value(); + + // Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, + // TitanOperationStatus> propertyImplNodes = + // titanGenericDao.getChildrenByEdgeCriteria(vertex, inputId, + // GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, + // PropertyValueData.class, props); + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), inputId, GraphEdgeLabels.GET_INPUT, NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<PropertyValueData, GraphEdge>> list = propertyImplNodes.left().value(); + + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List<ComponentInstanceProperty> result = new ArrayList<>(); + for (ImmutablePair<PropertyValueData, GraphEdge> propertyValueDataPair : list) { + PropertyValueData propertyValueData = propertyValueDataPair.left; + String propertyValueUid = propertyValueData.getUniqueId(); + String value = propertyValueData.getValue(); + + Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> propertyDefRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, PropertyData.class); + if (propertyDefRes.isRight()) { + TitanOperationStatus status = propertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + ImmutablePair<PropertyData, GraphEdge> propertyDefPair = propertyDefRes.left().value(); + PropertyData propertyData = propertyDefPair.left; + String propertyUniqueId = (String) propertyData.getPropertyDataDefinition().getUniqueId(); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueData.getUniqueId()); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + resourceInstanceProperty.setType(propertyData.getPropertyDataDefinition().getType()); + resourceInstanceProperty.setSchema(propertyData.getPropertyDataDefinition().getSchema()); + resourceInstanceProperty.setName((String) propertyValueDataPair.right.getProperties().get(GraphPropertiesDictionary.NAME.getProperty())); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + } + + public ComponentInstanceInput buildResourceInstanceInput(InputValueData propertyValueData, ComponentInstanceInput resourceInstanceInput) { + + String value = propertyValueData.getValue(); + String uid = propertyValueData.getUniqueId(); + ComponentInstanceInput instanceProperty = new ComponentInstanceInput(resourceInstanceInput, value, uid); + instanceProperty.setPath(resourceInstanceInput.getPath()); + + return instanceProperty; + } + + public Either<List<ComponentInstanceInput>, TitanOperationStatus> getAllInputsOfResourceInstance(ComponentInstance compInstance) { + + Either<List<ComponentInstanceInput>, TitanOperationStatus> result; + + return getAllInputsOfResourceInstanceOnlyInputDefId(compInstance.getUniqueId()); + + } + + public Either<List<InputDefinition>, StorageOperationStatus> addInputsToComponent(String resourceId, NodeTypeEnum nodeType, ComponentInstInputsMap componentInsInputs, Map<String, DataTypeDefinition> dataTypes) { + List<InputDefinition> resList = new ArrayList<InputDefinition>(); + Map<String, List<InputDefinition>> newInputsMap = componentInsInputs.getComponentInstanceInputsMap(); + if (newInputsMap != null && !newInputsMap.isEmpty()) { + for (Entry<String, List<InputDefinition>> entry : newInputsMap.entrySet()) { + String compInstId = entry.getKey(); + List<InputDefinition> inputs = entry.getValue(); + + if (inputs != null && !inputs.isEmpty()) { + for (InputDefinition input : inputs) { + + Either<Integer, StorageOperationStatus> counterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(compInstId, GraphPropertiesDictionary.INPUT_COUNTER, true); + if (counterRes.isRight()) { + log.debug("increaseAndGetResourceInputCounter failed resource instance {}", compInstId); + StorageOperationStatus status = counterRes.right().value(); + return Either.right(status); + } + + Either<InputDefinition, TitanOperationStatus> oldInputEither = getInputFromGraph(input.getUniqueId(), true, true); + if (oldInputEither.isRight()) { + log.error("Failed to get input {} ", input.getUniqueId()); + + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(oldInputEither.right().value())); + } + JSONObject jobject = new JSONObject(); + jobject.put("get_input", input.getName()); + InputDefinition oldInput = oldInputEither.left().value(); + + ComponentInstanceInput inputValue = new ComponentInstanceInput(oldInput, jobject.toJSONString(), null); + Integer index = counterRes.left().value(); + + Either<ComponentInstanceInput, StorageOperationStatus> eitherStatus = componentInstanceOperation.addInputValueToResourceInstance(inputValue, compInstId, index, true); + + if (eitherStatus.isRight()) { + log.error("Failed to add input value {} to resource instance {} in Graph. status is {}", inputValue, compInstId, eitherStatus.right().value().name()); + + return Either.right(eitherStatus.right().value()); + } + ComponentInstanceInput inputValueData = eitherStatus.left().value(); + + // ComponentInstanceInput propertyValueResult = + // buildResourceInstanceInput(propertyValueData, + // inputValue); + // log.debug("The returned ResourceInstanceProperty is " + // + propertyValueResult); + + String inputName = input.getName(); + input.setSchema(oldInputEither.left().value().getSchema()); + input.setDefaultValue(oldInput.getDefaultValue()); + input.setConstraints(oldInput.getConstraints()); + input.setDescription(oldInput.getDescription()); + input.setHidden(oldInput.isHidden()); + input.setImmutable(oldInput.isImmutable()); + input.setDefinition(oldInput.isDefinition()); + input.setRequired(oldInput.isRequired()); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(input, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", input, validateAndUpdateProperty); + return Either.right(validateAndUpdateProperty); + } + + Either<InputsData, TitanOperationStatus> addPropertyToGraph = addInputToGraph(inputName, input, resourceId, nodeType); + + if (addPropertyToGraph.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertyToGraph.right().value())); + } + InputDefinition createdInputyDefinition = convertInputDataToInputDefinition(addPropertyToGraph.left().value()); + createdInputyDefinition.setName(inputName); + createdInputyDefinition.setParentUniqueId(resourceId); + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), createdInputyDefinition.getName()); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), compInstId); + + GraphNode propertyData = new UniqueIdData(NodeTypeEnum.InputValue, inputValueData.getValueUniqueUid()); + + Either<GraphRelation, TitanOperationStatus> addPropRefResult = titanGenericDao.createRelation(addPropertyToGraph.left().value(), propertyData, GraphEdgeLabels.GET_INPUT, props); + + if (addPropRefResult.isRight()) { + TitanOperationStatus status = addPropRefResult.right().value(); + String description = "Failed to associate input " + addPropertyToGraph.left().value().getUniqueId() + " to input value " + inputValueData.getUniqueId() + " in graph. Status is " + status; + BeEcompErrorManager.getInstance().logInternalFlowError(ASSOCIATING_INPUT_TO_PROP, description, ErrorSeverity.ERROR); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + resList.add(createdInputyDefinition); + + } + } + + } + } + return Either.left(resList); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java new file mode 100644 index 0000000000..0d29c18a95 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java @@ -0,0 +1,1308 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.cassandra.transport.Event.StatusChange; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.InterfaceDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.OperationDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.InterfaceData; +import org.openecomp.sdc.be.resources.data.OperationData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("interface-operation") +public class InterfaceLifecycleOperation implements IInterfaceLifecycleOperation { + + private static Logger log = LoggerFactory.getLogger(InterfaceLifecycleOperation.class.getName()); + + public InterfaceLifecycleOperation() { + super(); + } + + @javax.annotation.Resource + private ArtifactOperation artifactOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName) { + + return addInterfaceToResource(interf, resourceId, interfaceName, false); + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> addInterfaceToResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean inTransaction) { + + return createInterfaceOnResource(interf, resourceId, interfaceName, true, inTransaction); + + } + + private Either<OperationData, TitanOperationStatus> addOperationToGraph(InterfaceDefinition interf, String opName, + Operation op, InterfaceData interfaceData) { + + op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId((String) interfaceData.getUniqueId(), opName)); + OperationData operationData = new OperationData(op); + + log.debug("Before adding operation to graph {}", operationData); + Either<OperationData, TitanOperationStatus> createOpNodeResult = titanGenericDao.createNode(operationData, + OperationData.class); + log.debug("After adding operation to graph {}", operationData); + + if (createOpNodeResult.isRight()) { + TitanOperationStatus opStatus = createOpNodeResult.right().value(); + log.error("Failed to add operation {} to graph. Status is {}", opName, opStatus); + return Either.right(opStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), opName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, + operationData, GraphEdgeLabels.INTERFACE_OPERATION, props); + + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createOpNodeResult.right().value(); + log.error("Failed to associate operation {} to property {} in graph. Status is {}", interfaceData.getUniqueId(), opName, operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createOpNodeResult.left().value()); + + } + + private Either<TitanVertex, TitanOperationStatus> addOperationToGraph(InterfaceDefinition interf, String opName, + Operation op, TitanVertex interfaceVertex) { + + String interfaceId = (String) titanGenericDao.getProperty(interfaceVertex, + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + op.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(interfaceId, opName)); + OperationData operationData = new OperationData(op); + + log.debug("Before adding operation to graph {}", operationData); + Either<TitanVertex, TitanOperationStatus> createOpNodeResult = titanGenericDao.createNode(operationData); + + if (createOpNodeResult.isRight()) { + TitanOperationStatus opStatus = createOpNodeResult.right().value(); + log.error("Failed to add operation {} to graph. status is {}", opName, opStatus); + return Either.right(opStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), opName); + TitanVertex operationVertex = createOpNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(interfaceVertex, operationVertex, + GraphEdgeLabels.INTERFACE_OPERATION, props); + + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate operation {} to property {} in graph. status is {}", interfaceId, opName, + createRelResult); + + return Either.right(createRelResult); + } + return Either.left(operationVertex); + } + + private InterfaceDefinition convertInterfaceDataToInterfaceDefinition(InterfaceData interfaceData) { + + log.debug("The object returned after create interface is {}", interfaceData); + + InterfaceDefinition interfaceDefResult = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition()); + + return interfaceDefResult; + + } + + private Operation convertOperationDataToOperation(OperationData operationData) { + + log.debug("The object returned after create operation is {}", operationData); + + Operation operationDefResult = new Operation(operationData.getOperationDataDefinition()); + + return operationDefResult; + + } + + private Either<InterfaceData, TitanOperationStatus> addInterfaceToGraph(InterfaceDefinition interfaceInfo, + String interfaceName, String resourceId) { + + InterfaceData interfaceData = new InterfaceData(interfaceInfo); + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + String interfaceNameSplitted = getShortInterfaceName(interfaceInfo); + + interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + + Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao + .getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class); + + if (existInterface.isRight()) { + + return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, resourceData); + } else { + log.debug("Interface {} already exist", interfaceData.getUniqueId()); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + + private Either<TitanVertex, TitanOperationStatus> addInterfaceToGraph(InterfaceDefinition interfaceInfo, + String interfaceName, String resourceId, TitanVertex metadataVertex) { + + InterfaceData interfaceData = new InterfaceData(interfaceInfo); + + String interfaceNameSplitted = getShortInterfaceName(interfaceInfo); + + interfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + + Either<TitanVertex, TitanOperationStatus> existInterface = titanGenericDao + .getVertexByProperty(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId()); + + if (existInterface.isRight()) { + + return createInterfaceNodeAndRelation(interfaceNameSplitted, resourceId, interfaceData, metadataVertex); + } else { + log.debug("Interface {} already exist", interfaceData.getUniqueId()); + return Either.right(TitanOperationStatus.ALREADY_EXIST); + } + } + + private Either<InterfaceData, TitanOperationStatus> createInterfaceNodeAndRelation(String interfaceName, + String resourceId, InterfaceData interfaceData, ResourceMetadataData resourceData) { + log.debug("Before adding interface to graph {}", interfaceData); + Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, + InterfaceData.class); + log.debug("After adding property to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. Status is {}", interfaceName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, + interfaceData, GraphEdgeLabels.INTERFACE, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", resourceId, interfaceName, operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + private Either<TitanVertex, TitanOperationStatus> createInterfaceNodeAndRelation(String interfaceName, + String resourceId, InterfaceData interfaceData, TitanVertex metadataVertex) { + log.debug("Before adding interface to graph {}", interfaceData); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. status is {}", interfaceName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName); + TitanVertex interfaceVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, interfaceVertex, + GraphEdgeLabels.INTERFACE, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, + interfaceName, createRelResult); + } + return Either.left(interfaceVertex); + } + + private Either<OperationData, TitanOperationStatus> createOperationNodeAndRelation(String operationName, + OperationData operationData, InterfaceData interfaceData) { + log.debug("Before adding operation to graph {}", operationData); + Either<OperationData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(operationData, + OperationData.class); + log.debug("After adding operation to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interfoperationce {} to graph. Status is {}", operationName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), operationName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(interfaceData, + operationData, GraphEdgeLabels.INTERFACE_OPERATION, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate operation {} to interface {} in graph. Status is {}", operationName, interfaceData.getUniqueId(), operationStatus); + + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + } + + // @Override + // public Either<InterfaceDefinition, StorageOperationStatus> getInterface( + // String interfaceId) { + // + // /* + // * Either<InterfaceData, TitanOperationStatus> getResult = + // * this.titanGenericDao + // * .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), + // * interfaceId, InterfaceData.class); if (getResult.isLeft()) { + // * InterfaceData propertyData = getResult.left().value(); return + // * Either.left(convertPropertyDataToPropertyDefinition(propertyData)); } + // * else { TitanOperationStatus titanStatus = getResult.right().value(); + // * log.debug("Node with id {} was not found in the graph. Status: {}", propertyId, titanStatus); + // * StorageOperationStatus storageOperationStatus = + // * DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + // * return Either.right(storageOperationStatus); } + // */ + // return null; + // } + + // @Override + // public Either<InterfaceDefinition, StorageOperationStatus> getInterface( + // String interfaceId, boolean inTransaction) { + // // TODO Auto-generated method stub + // return null; + // } + + @Override + public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource( + String resourceIdn, boolean recursively) { + return getAllInterfacesOfResource(resourceIdn, recursively, false); + } + + @Override + public Either<Map<String, InterfaceDefinition>, StorageOperationStatus> getAllInterfacesOfResource( + String resourceId, boolean recursively, boolean inTransaction) { + + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> result = null; + Map<String, InterfaceDefinition> interfaces = new HashMap<String, InterfaceDefinition>(); + try { + if ((resourceId == null) || resourceId.isEmpty()) { + log.error("resourceId is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + TitanOperationStatus findInterfacesRes = TitanOperationStatus.GENERAL_ERROR; + if (recursively) { + findInterfacesRes = findAllInterfacesRecursively(resourceId, interfaces); + } else { + findInterfacesRes = findAllInterfacesNotRecursively(resourceId, interfaces); + } + if (!findInterfacesRes.equals(TitanOperationStatus.OK)) { + log.error("Failed to get all interfaces of resource {}. Status is {}", resourceId, findInterfacesRes); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(findInterfacesRes)); + return result; + } + result = Either.left(interfaces); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus findAllInterfacesNotRecursively(String resourceId, + Map<String, InterfaceDefinition> interfaces) { + + Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> interfaceNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (interfaceNodes.isRight()) { + TitanOperationStatus status = interfaceNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } else { + List<ImmutablePair<InterfaceData, GraphEdge>> interfaceList = interfaceNodes.left().value(); + if (interfaceList != null) { + for (ImmutablePair<InterfaceData, GraphEdge> interfacePair : interfaceList) { + String interfaceUniqueId = (String) interfacePair.getKey().getUniqueId(); + Either<String, TitanOperationStatus> interfaceNameRes = getPropertyValueFromEdge( + interfacePair.getValue(), GraphPropertiesDictionary.NAME); + if (interfaceNameRes.isRight()) { + log.error("The requirement name is missing on the edge of requirement {}", interfaceUniqueId); + return interfaceNameRes.right().value(); + } + String interfaceName = interfaceNameRes.left().value(); + Either<InterfaceDefinition, TitanOperationStatus> interfaceDefRes = getNonRecursiveInterface( + interfacePair.getKey()); + if (interfaceDefRes.isRight()) { + TitanOperationStatus status = interfaceDefRes.right().value(); + log.error("Failed to get interface actions of interface {}", interfaceUniqueId); + return status; + } + + InterfaceDefinition interfaceDefinition = interfaceDefRes.left().value(); + if (true == interfaces.containsKey(interfaceName)) { + log.debug("The interface {} was already defined in derived resource. add not overriden operations", interfaceName); + InterfaceDefinition existInterface = interfaces.get(interfaceName); + addMissingOperationsToInterface(interfaceDefinition, existInterface); + } else { + interfaces.put(interfaceName, interfaceDefinition); + } + + } + } + } + return TitanOperationStatus.OK; + } + + public TitanOperationStatus findAllInterfacesRecursively(String resourceId, + Map<String, InterfaceDefinition> interfaces) { + + TitanOperationStatus findAllInterfacesNotRecursively = findAllInterfacesNotRecursively(resourceId, interfaces); + if (!findAllInterfacesNotRecursively.equals(TitanOperationStatus.OK)) { + log.error("failed to get interfaces for resource {}. Status is {}", resourceId, findAllInterfacesNotRecursively); + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Finish to lookup for parnet interfaces"); + return TitanOperationStatus.OK; + } else { + log.error("Failed to find parent interfaces of resource {}. Status is {}", resourceId, parentNodesStatus); + return parentNodesStatus; + } + } + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentIntStatus = findAllInterfacesRecursively(parentUniqueId, interfaces); + + if (addParentIntStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch all interfaces of resource {}", parentUniqueId); + return addParentIntStatus; + } + + return TitanOperationStatus.OK; + } + + private Either<String, TitanOperationStatus> getPropertyValueFromEdge(GraphEdge edge, + GraphPropertiesDictionary property) { + Map<String, Object> edgeProps = edge.getProperties(); + String interfaceName = null; + if (edgeProps != null) { + interfaceName = (String) edgeProps.get(property.getProperty()); + if (interfaceName == null) { + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + } else { + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + return Either.left(interfaceName); + } + + private Either<InterfaceDefinition, TitanOperationStatus> getNonRecursiveInterface(InterfaceData interfaceData) { + + log.debug("Going to fetch the operations associate to interface {}", interfaceData.getUniqueId()); + InterfaceDefinition interfaceDefinition = new InterfaceDefinition(interfaceData.getInterfaceDataDefinition()); + + String interfaceId = interfaceData.getUniqueId(); + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationsRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), interfaceId, + GraphEdgeLabels.INTERFACE_OPERATION, NodeTypeEnum.InterfaceOperation, OperationData.class); + + if (operationsRes.isRight()) { + TitanOperationStatus status = operationsRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + return Either.left(interfaceDefinition); + } + } + + List<ImmutablePair<OperationData, GraphEdge>> operationList = operationsRes.left().value(); + if (operationList != null && !operationList.isEmpty()) { + for (ImmutablePair<OperationData, GraphEdge> operationPair : operationList) { + Operation operation = new Operation(operationPair.getKey().getOperationDataDefinition()); + Either<String, TitanOperationStatus> operationNameRes = getPropertyValueFromEdge( + operationPair.getValue(), GraphPropertiesDictionary.NAME); + if (operationNameRes.isRight()) { + log.error("The operation name is missing on the edge of operation {}", operationPair.getKey().getUniqueId()); + return Either.right(operationNameRes.right().value()); + } + String operationName = operationNameRes.left().value(); + findOperationImplementation(operation); + interfaceDefinition.getOperations().put(operationName, operation); + } + } + + return Either.left(interfaceDefinition); + } + + private StorageOperationStatus findOperationImplementation(Operation operation) { + + String operationId = operation.getUniqueId(); + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifactsRes = artifactOperation + .getArtifacts(operationId, NodeTypeEnum.InterfaceOperation, true); + if (artifactsRes.isRight() || artifactsRes.left().value() == null) { + log.error("failed to get artifact from graph for operation id {}. status is {}", operationId, + artifactsRes.right().value()); + return artifactsRes.right().value(); + } else { + Map<String, ArtifactDefinition> artifacts = artifactsRes.left().value(); + Iterator<String> iter = artifacts.keySet().iterator(); + + if (iter.hasNext()) { + operation.setImplementation(artifacts.get(iter.next())); + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus addMissingOperationsToInterface(InterfaceDefinition interfaceDefinition, + InterfaceDefinition existInterface) { + Map<String, Operation> existOperations = existInterface.getOperations(); + Map<String, Operation> operations = interfaceDefinition.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set<Entry<String, Operation>> operationsSet = operations.entrySet(); + for (Entry<String, Operation> operation : operationsSet) { + if (!existOperations.containsKey(operation.getKey())) { + existOperations.put(operation.getKey(), operation.getValue()); + } + } + } + return StorageOperationStatus.OK; + } + + @Override + public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation interf) { + + return updateInterfaceOperation(resourceId, interfaceName, operationName, interf, false); + } + + @Override + public Either<Operation, StorageOperationStatus> updateInterfaceOperation(String resourceId, String interfaceName, + String operationName, Operation operation, boolean inTransaction) { + Either<Operation, StorageOperationStatus> status = updateOperationOnGraph(operation, resourceId, interfaceName, + operationName); + + /* + * if (status.isRight()) { if (false == inTransaction) { + * titanGenericDao.rollback(); } log.error("Failed to update operation " + * + operationName + " of interfaceName " + interfaceName + + * " of resource" + resourceId); return Either.right(DaoStatusConverter + * .convertTitanStatusToStorageStatus(status.right().value())); } else { + * if (false == inTransaction) { titanGenericDao.commit(); } + * OperationData operationData = status.left().value(); + * + * Operation operationDefResult = + * convertOperationDataToOperation(operationData); + * + * + * log.debug("The returned OperationDefintion is {}", operationDefResult); return Either.left(operationDefResult); } + */ + return status; + } + + private Either<Operation, StorageOperationStatus> updateOperationOnGraph(Operation operation, String resourceId, + String interfaceName, String operationName) { + + Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (childrenNodes.isRight()) { + /* + * InterfaceDefinition intDef = new InterfaceDefinition(); + * intDef.setType(interfaceName); Map<String, Operation> opMap = new + * HashMap<String, Operation>(); opMap.put(operationName, + * operation); intDef.setOperations(opMap); + * Either<InterfaceDefinition, StorageOperationStatus> statusRes = + * this .createInterfaceOnResource(intDef, resourceId, + * interfaceName, true); if (statusRes.isRight()) return + * Either.right(statusRes.right().value()); else { + * InterfaceDefinition newDef = statusRes.left().value(); Operation + * res = newDef.getOperations().get(operationName); return + * Either.left(res); } + */ + return updateOperationFromParentNode(operation, resourceId, interfaceName, operationName); + + } else { + return updateExistingOperation(resourceId, operation, interfaceName, operationName, childrenNodes); + + } + + } + + private Either<Operation, StorageOperationStatus> updateExistingOperation(String resourceId, Operation operation, + String interfaceName, String operationName, + Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes) { + Operation newOperation = null; + StorageOperationStatus storageOperationStatus = StorageOperationStatus.GENERAL_ERROR; + + for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties(); + InterfaceData interfaceData = interfaceDataNode.getKey(); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) { + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceDataNode.getLeft().getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {} on interface {}", operationName, interfaceName); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + } else { + List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value(); + for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map<String, Object> opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) { + ArtifactDefinition artifact = operation.getImplementation(); + Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) opData.getUniqueId(), GraphEdgeLabels.ARTIFACT_REF, + NodeTypeEnum.ArtifactRef, ArtifactData.class); + Either<ArtifactDefinition, StorageOperationStatus> artStatus; + if (artifactRes.isRight()) { + artStatus = artifactOperation.addArifactToComponent(artifact, + (String) operationPairEdge.getLeft().getUniqueId(), + NodeTypeEnum.InterfaceOperation, true, true); + } else { + artStatus = artifactOperation.updateArifactOnResource(artifact, + (String) operationPairEdge.getLeft().getUniqueId(), + (String) artifactRes.left().value().getLeft().getUniqueId(), + NodeTypeEnum.InterfaceOperation, true); + } + if (artStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {}", operationName, interfaceName); + return Either.right(artStatus.right().value()); + } else { + newOperation = this.convertOperationDataToOperation(opData); + newOperation.setImplementation(artStatus.left().value()); + + } + + } + + } + if (newOperation == null) { + Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode( + resourceId, interfaceName); + if (parentInterfaceStatus.isRight()) { + log.debug("Interface {} not exist", interfaceName); + return Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value())); + } + + InterfaceData parentInterfaceData = parentInterfaceStatus.left().value(); + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> opRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) parentInterfaceData.getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (opRes.isRight()) { + log.error("Failed to find operation {} on interface", operationName, interfaceName); + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + + } else { + List<ImmutablePair<OperationData, GraphEdge>> parentOperations = opRes.left().value(); + for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : parentOperations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map<String, Object> opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()) + .equals(operationName)) { + return copyAndCreateNewOperation(operation, interfaceName, operationName, null, + interfaceData, operationRes, opData); + } + } + } + + } + + } + + } else { + // not found + storageOperationStatus = StorageOperationStatus.ARTIFACT_NOT_FOUND; + } + + } + if (newOperation == null) + return Either.right(storageOperationStatus); + else + return Either.left(newOperation); + } + + private Either<Operation, StorageOperationStatus> copyAndCreateNewOperation(Operation operation, + String interfaceName, String operationName, Operation newOperation, InterfaceData interfaceData, + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes, + OperationData opData) { + OperationDataDefinition opDataInfo = opData.getOperationDataDefinition(); + OperationDataDefinition newOperationInfo = new OperationDataDefinition(opDataInfo); + newOperationInfo.setUniqueId( + UniqueIdBuilder.buildPropertyUniqueId(interfaceData.getUniqueId(), operationName.toLowerCase())); + OperationData newopData = new OperationData(newOperationInfo); + Either<OperationData, TitanOperationStatus> operationStatus = createOperationNodeAndRelation(operationName, + newopData, interfaceData); + if (operationStatus.isRight()) { + log.error("Failed to create operation {} on interface {}", operationName, interfaceName); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + } + ArtifactDefinition artifact = operation.getImplementation(); + if (artifact != null) { + Either<ArtifactDefinition, StorageOperationStatus> artStatus = artifactOperation.addArifactToComponent( + artifact, (String) operationStatus.left().value().getUniqueId(), NodeTypeEnum.InterfaceOperation, + true, true); + if (artStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + } else { + newOperation = this.convertOperationDataToOperation(opData); + newOperation.setImplementation(artStatus.left().value()); + + } + } + return Either.left(newOperation); + } + + private Either<Operation, StorageOperationStatus> updateOperationFromParentNode(Operation operation, + String resourceId, String interfaceName, String operationName) { + // Operation newOperation = null; + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + Either<InterfaceData, TitanOperationStatus> parentInterfaceStatus = findInterfaceOnParentNode(resourceId, + interfaceName); + if (parentInterfaceStatus.isRight()) { + log.debug("Interface {} not exist", interfaceName); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentInterfaceStatus.right().value())); + } + + InterfaceData interfaceData = parentInterfaceStatus.left().value(); + InterfaceDataDefinition intDataDefinition = interfaceData.getInterfaceDataDefinition(); + InterfaceDataDefinition newInterfaceInfo = new InterfaceDataDefinition(intDataDefinition); + + String interfaceNameSplitted = getShortInterfaceName(intDataDefinition); + + newInterfaceInfo.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, interfaceNameSplitted)); + InterfaceData updatedInterfaceData = new InterfaceData(newInterfaceInfo); + Either<InterfaceData, TitanOperationStatus> createStatus = createInterfaceNodeAndRelation(interfaceName, + resourceId, updatedInterfaceData, resourceData); + if (createStatus.isRight()) { + log.debug("failed to create interface node {} on resource {}", interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(createStatus.right().value())); + } + + InterfaceData newInterfaceNode = createStatus.left().value(); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(newInterfaceNode, + interfaceData, GraphEdgeLabels.DERIVED_FROM, null); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate interface {} to interface {} in graph. Status is {}", interfaceData.getUniqueId(), newInterfaceNode.getUniqueId(), operationStatus); + + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + } + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceData.getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {} on interface {}", operationName, interfaceName); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationRes.right().value())); + + } else { + List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value(); + for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) { + GraphEdge opEdge = operationPairEdge.getRight(); + OperationData opData = operationPairEdge.getLeft(); + Map<String, Object> opEdgeProp = opEdge.getProperties(); + if (opEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(operationName)) { + + return copyAndCreateNewOperation(operation, interfaceName, operationName, null, // changed + // from + // newOperation + newInterfaceNode, operationRes, opData); + + } + } + } + // if(newOperation == null) + return Either.right(StorageOperationStatus.GENERAL_ERROR); + // else + // return Either.left(newOperation); + } + + private Either<InterfaceData, TitanOperationStatus> findInterfaceOnParentNode(String resourceId, + String interfaceName) { + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentRes.isRight()) { + log.debug("interface {} not found", interfaceName); + return Either.right(parentRes.right().value()); + } + ImmutablePair<ResourceMetadataData, GraphEdge> parenNode = parentRes.left().value(); + + Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + parenNode.getKey().getMetadataDataDefinition().getUniqueId(), GraphEdgeLabels.INTERFACE, + NodeTypeEnum.Interface, InterfaceData.class); + if (childrenNodes.isRight()) { + return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), + interfaceName); + + } else { + for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties(); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceName)) { + return Either.left(interfaceDataNode.getKey()); + } + + } + return findInterfaceOnParentNode(parenNode.getKey().getMetadataDataDefinition().getUniqueId(), + interfaceName); + } + + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceOnResource(InterfaceDefinition interf, + String resourceId, String interfaceName, boolean failIfExist, boolean inTransaction) { + + Either<InterfaceData, TitanOperationStatus> status = addInterfaceToGraph(interf, interfaceName, resourceId); + + if (status.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add interface {} to resource {}", interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + + if (false == inTransaction) { + titanGenericDao.commit(); + } + InterfaceData interfaceData = status.left().value(); + + InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData); + Map<String, Operation> operations = interf.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set<String> opNames = operations.keySet(); + Map<String, Operation> newOperations = new HashMap<String, Operation>(); + for (String operationName : opNames) { + + Operation op = operations.get(operationName); + Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, operationName, + op, interfaceData); + if (status.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add operation {} to interface {}", operationName, interfaceName); + } else if (status.isLeft()) { + if (false == inTransaction) { + titanGenericDao.commit(); + } + OperationData opData = opStatus.left().value(); + Operation newOperation = this.convertOperationDataToOperation(opData); + + ArtifactDefinition art = op.getImplementation(); + if (art != null) { + Either<ArtifactDefinition, StorageOperationStatus> artRes = artifactOperation + .addArifactToComponent(art, (String) opData.getUniqueId(), + NodeTypeEnum.InterfaceOperation, failIfExist, true); + if (artRes.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + } else { + newOperation.setImplementation(artRes.left().value()); + } + newOperations.put(operationName, newOperation); + } + } + } + interfaceDefResult.setOperations(newOperations); + } + log.debug("The returned InterfaceDefintion is {}", interfaceDefResult); + return Either.left(interfaceDefResult); + } + + } + + @Override + public StorageOperationStatus createInterfaceOnResource(InterfaceDefinition interf, String resourceId, + String interfaceName, boolean failIfExist, boolean inTransaction, TitanVertex metadataVertex) { + + Either<TitanVertex, TitanOperationStatus> interfaceResult = addInterfaceToGraph(interf, interfaceName, + resourceId, metadataVertex); + + if (interfaceResult.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add interface {} to resource {}", interfaceName, resourceId); + return DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceResult.right().value()); + } else { + + if (false == inTransaction) { + titanGenericDao.commit(); + } + TitanVertex interfaceVertex = interfaceResult.left().value(); + + // InterfaceDefinition interfaceDefResult = + // convertInterfaceDataToInterfaceDefinition(interfaceData); + Map<String, Operation> operations = interf.getOperations(); + if (operations != null && !operations.isEmpty()) { + Set<String> opNames = operations.keySet(); + for (String operationName : opNames) { + + Operation op = operations.get(operationName); + Either<TitanVertex, TitanOperationStatus> operationResult = addOperationToGraph(interf, + operationName, op, interfaceVertex); + if (operationResult.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add operation {} to interface {}", operationName, interfaceName); + return DaoStatusConverter.convertTitanStatusToStorageStatus(operationResult.right().value()); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + TitanVertex operationVertex = operationResult.left().value(); + + ArtifactDefinition art = op.getImplementation(); + if (art != null) { + String opId = (String) titanGenericDao.getProperty(operationVertex, + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + StorageOperationStatus artRes = artifactOperation.addArifactToComponent(art, opId, + NodeTypeEnum.InterfaceOperation, failIfExist, operationVertex); + if (!artRes.equals(StorageOperationStatus.OK)) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to add artifact {} to interface {}", operationName, interfaceName); + return artRes; + } + } + } + } + } + return StorageOperationStatus.OK; + } + + } + + @Override + public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, + String operationId) { + return deleteInterfaceOperation(resourceId, interfaceName, operationId, false); + } + + @Override + public Either<Operation, StorageOperationStatus> deleteInterfaceOperation(String resourceId, String interfaceName, + String operationId, boolean inTransaction) { + + Either<Operation, TitanOperationStatus> status = removeOperationOnGraph(resourceId, interfaceName, operationId); + if (status.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to delete operation {} of interface {} resource {}", operationId, interfaceName, resourceId); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status.right().value())); + } else { + if (false == inTransaction) { + titanGenericDao.commit(); + } + + Operation opDefResult = status.left().value();// convertOperationDataToOperation(operationData); + log.debug("The returned Operation is {}", opDefResult); + return Either.left(opDefResult); + } + + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> deleteInterfaceOfResourceOnGraph(String resourceId, + InterfaceDefinition interfaceDef, boolean inTransaction) { + + Map<String, Operation> operations = interfaceDef.getOperations(); + String interfaceNameSplitted = getShortInterfaceName(interfaceDef); + if (operations != null) { + for (Entry<String, Operation> entry : operations.entrySet()) { + + Operation op = entry.getValue(); + Either<Operation, StorageOperationStatus> removeOperationFromResource = deleteInterfaceOperation( + resourceId, interfaceNameSplitted, op.getUniqueId(), true); + if (removeOperationFromResource.isRight()) { + if (false == inTransaction) { + titanGenericDao.rollback(); + } + log.error("Failed to delete operation {} of interface {} resource {}", op.getUniqueId(), interfaceDef.getType(), resourceId); + return Either.right(removeOperationFromResource.right().value()); + } + } + } + return Either.left(interfaceDef); + + } + + private Either<Operation, TitanOperationStatus> removeOperationOnGraph(String resourceId, String interfaceName, + String operationId) { + log.debug("Before deleting operation from graph {}", operationId); + + Either<List<ImmutablePair<InterfaceData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId, + GraphEdgeLabels.INTERFACE, NodeTypeEnum.Interface, InterfaceData.class); + + if (childrenNodes.isRight()) { + log.debug("Not found interface {}", interfaceName); + return Either.right(childrenNodes.right().value()); + } + OperationData opData = null; + for (ImmutablePair<InterfaceData, GraphEdge> interfaceDataNode : childrenNodes.left().value()) { + + GraphEdge interfaceEdge = interfaceDataNode.getRight(); + Map<String, Object> interfaceEdgeProp = interfaceEdge.getProperties(); + + String interfaceSplitedName = splitType(interfaceName); + + if (interfaceEdgeProp.get(GraphPropertiesDictionary.NAME.getProperty()).equals(interfaceSplitedName)) { + Either<List<ImmutablePair<OperationData, GraphEdge>>, TitanOperationStatus> operationRes = titanGenericDao + .getChildrenNodes(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) interfaceDataNode.getLeft().getUniqueId(), GraphEdgeLabels.INTERFACE_OPERATION, + NodeTypeEnum.InterfaceOperation, OperationData.class); + if (operationRes.isRight()) { + log.error("Failed to find operation {}", operationId, interfaceName); + return Either.right(operationRes.right().value()); + } + List<ImmutablePair<OperationData, GraphEdge>> operations = operationRes.left().value(); + + for (ImmutablePair<OperationData, GraphEdge> operationPairEdge : operations) { + + opData = operationPairEdge.getLeft(); + if (opData.getUniqueId().equals(operationId)) { + + Either<ImmutablePair<ArtifactData, GraphEdge>, TitanOperationStatus> artifactRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + (String) operationPairEdge.getLeft().getUniqueId(), + GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class); + Either<ArtifactDefinition, StorageOperationStatus> arStatus = null; + if (artifactRes.isLeft()) { + ArtifactData arData = artifactRes.left().value().getKey(); + arStatus = artifactOperation.removeArifactFromResource( + (String) operationPairEdge.getLeft().getUniqueId(), (String) arData.getUniqueId(), + NodeTypeEnum.InterfaceOperation, true, true); + if (arStatus.isRight()) { + log.debug("failed to delete artifact {}", arData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + } + Either<OperationData, TitanOperationStatus> deleteOpStatus = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.InterfaceOperation), opData.getUniqueId(), + OperationData.class); + if (deleteOpStatus.isRight()) { + log.debug("failed to delete operation {}", opData.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + opData = deleteOpStatus.left().value(); + Operation operation = new Operation(opData.getOperationDataDefinition()); + if (arStatus != null) { + operation.setImplementation(arStatus.left().value()); + } + if (operations.size() <= 1) { + Either<InterfaceData, TitanOperationStatus> deleteInterfaceStatus = titanGenericDao + .deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), + interfaceDataNode.left.getUniqueId(), InterfaceData.class); + if (deleteInterfaceStatus.isRight()) { + log.debug("failed to delete interface {}", interfaceDataNode.left.getUniqueId()); + return Either.right(TitanOperationStatus.INVALID_ID); + } + + } + + return Either.left(operation); + + } + } + } + } + + log.debug("Not found operation {}", interfaceName); + return Either.right(TitanOperationStatus.INVALID_ID); + // } + + } + + private String splitType(String interfaceName) { + String interfaceSplittedName; + String[] packageName = interfaceName.split("\\."); + + if (packageName.length == 0) { + interfaceSplittedName = interfaceName; + } else { + interfaceSplittedName = packageName[packageName.length - 1]; + } + + return interfaceSplittedName.toLowerCase(); + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public void setArtifactOperation(ArtifactOperation artifactOperation) { + this.artifactOperation = artifactOperation; + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf, + boolean inTransaction) { + Either<InterfaceDefinition, StorageOperationStatus> result = null; + try { + + InterfaceData interfaceData = new InterfaceData(interf); + interf.setUniqueId(interf.getType().toLowerCase()); + + Either<InterfaceData, TitanOperationStatus> existInterface = titanGenericDao + .getNode(interfaceData.getUniqueIdKey(), interfaceData.getUniqueId(), InterfaceData.class); + + if (existInterface.isLeft()) { + // already exist + log.debug("Interface type already exist {}", interfaceData); + result = Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS); + return result; + } + + log.debug("Before adding interface type to graph {}", interfaceData); + Either<InterfaceData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(interfaceData, + InterfaceData.class); + log.debug("After adding property type to graph {}", interfaceData); + + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add interface {} to graph. Status is {}", interf.getType(), operationStatus); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(operationStatus)); + return result; + } + + InterfaceDefinition interfaceDefResult = convertInterfaceDataToInterfaceDefinition(interfaceData); + Map<String, Operation> operations = interf.getOperations(); + + if (operations != null && !operations.isEmpty()) { + Map<String, Operation> newOperations = new HashMap<String, Operation>(); + + for (Map.Entry<String, Operation> operation : operations.entrySet()) { + Either<OperationData, TitanOperationStatus> opStatus = addOperationToGraph(interf, + operation.getKey(), operation.getValue(), interfaceData); + if (opStatus.isRight()) { + titanGenericDao.rollback(); + log.error("Failed to add operation {} to interface {}", operation.getKey(), interf.getType()); + + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(opStatus.right().value())); + return result; + } else { + OperationData opData = opStatus.left().value(); + Operation newOperation = this.convertOperationDataToOperation(opData); + newOperations.put(operation.getKey(), newOperation); + } + } + interfaceDefResult.setOperations(newOperations); + } + result = Either.left(interfaceDefResult); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> getInterface(String interfaceId) { + Either<InterfaceData, TitanOperationStatus> getResult = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceId, InterfaceData.class); + if (getResult.isLeft()) { + InterfaceData interfaceData = getResult.left().value(); + return Either.left(convertInterfaceDataToInterfaceDefinition(interfaceData)); + } else { + TitanOperationStatus titanStatus = getResult.right().value(); + log.debug("Node with id {} was not found in the graph. Status: {}", interfaceId, titanStatus); + StorageOperationStatus storageOperationStatus = DaoStatusConverter + .convertTitanStatusToStorageStatus(titanStatus); + return Either.right(storageOperationStatus); + } + } + + @Override + public StorageOperationStatus associateInterfaceToNode(GraphNode node, InterfaceDefinition interfaceDefinition, + TitanVertex metadataVertex) { + + Either<TitanVertex, TitanOperationStatus> interfaceData = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDefinition.getUniqueId()); + if (interfaceData.isRight()) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceData.right().value()); + } + + Map<String, Object> properties = new HashMap<String, Object>(); + + String interfaceName = getShortInterfaceName(interfaceDefinition); + + properties.put(GraphPropertiesDictionary.NAME.getProperty(), interfaceName.toLowerCase()); + TitanOperationStatus createRelation = titanGenericDao.createEdge(metadataVertex, interfaceData.left().value(), + GraphEdgeLabels.INTERFACE, properties); + if (!createRelation.equals(TitanOperationStatus.OK)) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation); + } + + return StorageOperationStatus.OK; + } + + public String getShortInterfaceName(InterfaceDataDefinition interfaceDefinition) { + String[] packageName = interfaceDefinition.getType().split("\\."); + String interfaceName; + if (packageName.length == 0) { + interfaceName = interfaceDefinition.getType(); + } else { + interfaceName = packageName[packageName.length - 1]; + } + return interfaceName.toLowerCase(); + } + + /** + * + */ + public Either<InterfaceDefinition, StorageOperationStatus> createInterfaceType(InterfaceDefinition interf) { + return createInterfaceType(interf, false); + } + + @Override + public Either<Operation, StorageOperationStatus> getSpecificOperation(String resourceId, String interfaceType, + String operationName) { + log.trace("Getting operation, resourceId {}, interfaceType {}, operationName {}", resourceId, interfaceType, + operationName); + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = getAllInterfacesOfResource( + resourceId, false); + if (allInterfacesOfResource.isRight() || allInterfacesOfResource.left().value() == null + || allInterfacesOfResource.left().value().get(interfaceType) == null) { + log.debug("Couldn't find interface definition of type {} for resource id {}", interfaceType, resourceId); + return Either.right(allInterfacesOfResource.right().value()); + } + InterfaceDefinition interfaceDefinition = allInterfacesOfResource.left().value().get(interfaceType); + Map<String, Operation> operations = interfaceDefinition.getOperations(); + if (operations == null || operations.get(operationName) == null) { + log.debug("Couldn't find operation for operation name {}, interface type {}", operationName, interfaceType); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(operations.get(operationName)); + } + + @Override + public Either<InterfaceDefinition, StorageOperationStatus> dissociateInterfaceFromNode(GraphNode node, + InterfaceDefinition interfaceDefinition) { + + Either<InterfaceData, TitanOperationStatus> interfaceData = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Interface), interfaceDefinition.getUniqueId(), + InterfaceData.class); + if (interfaceData.isRight()) { + log.debug("Couldn't find interface {}", interfaceDefinition); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(interfaceData.right().value())); + } + + InterfaceData value = interfaceData.left().value(); + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(node, value, + GraphEdgeLabels.INTERFACE); + if (deleteRelation.isRight()) { + TitanOperationStatus status = deleteRelation.right().value(); + log.debug("Couldn't dissociate interface between node {} to node {}. Status is {}", node.getUniqueId(), + value.getUniqueId(), status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + return Either.left(interfaceDefinition); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java new file mode 100644 index 0000000000..863975893c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java @@ -0,0 +1,1143 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ComponentMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("lifecycle-operation") +public class LifecycleOperation implements ILifecycleOperation { + + public static final String VERSION_DELIMETER = "."; + public static final String VERSION_DELIMETER_REGEXP = "\\."; + + public LifecycleOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(LifecycleOperation.class.getName()); + + @javax.annotation.Resource + private ResourceOperation resourceOperation; + + @javax.annotation.Resource + private ServiceOperation serviceOperation; + + @javax.annotation.Resource + private ProductOperation productOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public ResourceOperation getResourceOperation() { + return resourceOperation; + } + + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + public ServiceOperation getServiceOperation() { + return serviceOperation; + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + if (NodeTypeEnum.Service.equals(componentType)) { + return serviceOperation; + } else if (NodeTypeEnum.Resource.equals(componentType)) { + return resourceOperation; + } else if (NodeTypeEnum.Product.equals(componentType)) { + return productOperation; + } + return null; + } + + public void setServiceOperation(ServiceOperation serviceOperation) { + this.serviceOperation = serviceOperation; + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<User, StorageOperationStatus> getComponentOwner(String resourceId, NodeTypeEnum nodeType, + boolean inTransaction) { + + Either<User, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either<ImmutablePair<UserData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode( + UniqueIdBuilder.getKeyByNodeType(nodeType), resourceId, GraphEdgeLabels.STATE, NodeTypeEnum.User, + UserData.class); + + if (parentNode.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(parentNode.right().value())); + } + + ImmutablePair<UserData, GraphEdge> value = parentNode.left().value(); + + User owner = new User(value.left); + result = Either.left(owner); + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + return result; + } + + @Override + public Either<? extends Component, StorageOperationStatus> checkoutComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + + try { + // update old component + if (!component.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + component.setHighestVersion(false); + ComponentOperation componentOperation = getComponentOperation(nodeType); + Either<? extends Component, StorageOperationStatus> updateComponent = componentOperation + .updateComponent(component, inTransaction, titanGenericDao, component.getClass(), nodeType); + if (updateComponent.isRight()) { + StorageOperationStatus error = updateComponent.right().value(); + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, error); + return Either.right(error); + } + + StorageOperationStatus changeStateToLastState = changeStateRelation(nodeType, component.getUniqueId(), + currentOwner, GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeStateToLastState.equals(StorageOperationStatus.OK)) { + result = Either.right(changeStateToLastState); + return result; + } + } + + // clone the component + result = cloneComponentForCheckout(component, nodeType, modifier); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, result.right().value()); + return result; + } + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + private Either<? extends Component, StorageOperationStatus> cloneComponentForCertified(Component component, + User modifier, Integer majorVersion) { + + // set new version + String certifiedVersion = (majorVersion + 1) + VERSION_DELIMETER + "0"; + component.setVersion(certifiedVersion); + component.setLifecycleState(LifecycleStateEnum.CERTIFIED); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + component.setHighestVersion(true); + + ComponentOperation componentOperation = getComponentOperation(component.getComponentType().getNodeType()); + Either<? extends Component, StorageOperationStatus> cloneComponentResult = componentOperation + .cloneComponent(component, certifiedVersion, LifecycleStateEnum.CERTIFIED, true); + + return cloneComponentResult; + } + + @Override + public Either<? extends Component, StorageOperationStatus> undoCheckout(NodeTypeEnum nodeType, Component component, + User modifier, User currentOwner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + ComponentOperation componentOperation = getComponentOperation(nodeType); + + // this is in case prevVersion is 0.0 - returning OOTB component + Component prevComponent = componentOperation.getDefaultComponent(); + try { + // find previous version + String[] versionParts = component.getVersion().split(VERSION_DELIMETER_REGEXP); + Integer minorVersion = Integer.parseInt(versionParts[1]) - 1; + String previousVersion = versionParts[0] + VERSION_DELIMETER + minorVersion; + + if (!previousVersion.equals("0.0")) { + Either<? extends Component, StorageOperationStatus> updateOldResourceResult = updateOldComponentBeforeUndoCheckout( + componentOperation, prevComponent, component, previousVersion, nodeType, true); + if (updateOldResourceResult.isRight()) { + result = updateOldResourceResult; + return result; + } + prevComponent = updateOldResourceResult.left().value(); + } + + // delete the component + Either<? extends Component, StorageOperationStatus> deleteResourceResult = componentOperation + .deleteComponent(component.getUniqueId(), true); + if (deleteResourceResult.isRight()) { + result = deleteResourceResult; + return result; + } + + // return the deleted resource + result = Either.left(prevComponent); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<? extends Component, StorageOperationStatus> checkinComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + try { + StorageOperationStatus updateCheckinInGraph = updateCheckinInGraph(nodeType, component.getUniqueId(), + component.getLifecycleState(), modifier, owner); + if (!updateCheckinInGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), + updateCheckinInGraph); + return Either.right(updateCheckinInGraph); + } + LifecycleStateEnum state = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN; + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private ComponentParametersView buildFilterForFetchComponentAfterChangeState() { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreUsers(false); + // Used when we running multiple change states and want to use the + // result from another change + // state(LifecycleOperationTest.certificationStatusChange) + componentParametersView.setIgnoreCategories(false); + return componentParametersView; + } + + private StorageOperationStatus updateCheckinInGraph(NodeTypeEnum componentType, String componentId, + LifecycleStateEnum state, User modifier, User owner) { + + // check if we cancel rfc + if (state.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + + // remove last checkin + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + UniqueIdData resourceData = new UniqueIdData(componentType, componentId); + Either<GraphRelation, TitanOperationStatus> deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(resourceData, GraphEdgeLabels.LAST_STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + return StorageOperationStatus.INCONSISTENCY; + } + } + + // remove CHECKOUT relation + StorageOperationStatus removeUserToResourceRelation = removeUserToResourceRelation(componentType, + owner.getUserId(), componentId, GraphEdgeLabels.STATE); + if (!removeUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return removeUserToResourceRelation; + } + + // create CHECKIN relation + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + StorageOperationStatus createUserToResourceRelation = createUserToResourceRelation(componentType, + modifier.getUserId(), componentId, GraphEdgeLabels.STATE, props); + if (!createUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return createUserToResourceRelation; + } + + return StorageOperationStatus.OK; + } + + @Override + public Either<? extends Component, StorageOperationStatus> requestCertificationComponent(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + try { + StorageOperationStatus updateRfcOnGraph = updateRfcOnGraph(nodeType, component.getUniqueId(), + component.getLifecycleState(), modifier, owner); + if (!updateRfcOnGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), + updateRfcOnGraph); + return Either.right(updateRfcOnGraph); + } + + LifecycleStateEnum state = LifecycleStateEnum.READY_FOR_CERTIFICATION; + + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + return result; + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus updateRfcOnGraph(NodeTypeEnum componentType, String componentId, + LifecycleStateEnum state, User modifier, User owner) { + + if (state.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + // if this is atomic checkin + RFC: create checkin relation + + // remove CHECKOUT relation + StorageOperationStatus relationStatus = removeUserToResourceRelation(componentType, owner.getUserId(), + componentId, GraphEdgeLabels.STATE); + if (!relationStatus.equals(StorageOperationStatus.OK)) { + return relationStatus; + } + + // create CHECKIN relation + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + relationStatus = createUserToResourceRelation(componentType, modifier.getUserId(), componentId, + GraphEdgeLabels.LAST_STATE, props); + if (!relationStatus.equals(StorageOperationStatus.OK)) { + return relationStatus; + } + } else { + StorageOperationStatus changeStatus = changeRelationLabel(componentType, componentId, owner, + GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeStatus.equals(StorageOperationStatus.OK)) { + return changeStatus; + } + } + + // create RFC relation + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + StorageOperationStatus changeRelationLabel = createUserToResourceRelation(componentType, modifier.getUserId(), + componentId, GraphEdgeLabels.STATE, props); + if (!changeRelationLabel.equals(StorageOperationStatus.OK)) { + return changeRelationLabel; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus changeRelationLabel(NodeTypeEnum componentType, String componentId, User owner, + GraphEdgeLabels prevLabel, GraphEdgeLabels toLabel) { + UniqueIdData resourceV = new UniqueIdData(componentType, componentId); + UserData userV = new UserData(); + userV.setUserId(owner.getUserId()); + Either<GraphRelation, TitanOperationStatus> replaceRelationLabelResult = titanGenericDao + .replaceRelationLabel(userV, resourceV, prevLabel, toLabel); + if (replaceRelationLabelResult.isRight()) { + log.error("failed to replace label from last state to state"); + return DaoStatusConverter.convertTitanStatusToStorageStatus(replaceRelationLabelResult.right().value()); + } + return StorageOperationStatus.OK; + } + + @Override + public Either<? extends Component, StorageOperationStatus> startComponentCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + try { + StorageOperationStatus updateOnGraph = updateStartCertificationOnGraph(nodeType, component.getUniqueId(), + modifier, owner); + if (!updateOnGraph.equals(StorageOperationStatus.OK)) { + log.error("failed to update state of resource {}. status={}", component.getUniqueId(), updateOnGraph); + return Either.right(updateOnGraph); + } + + LifecycleStateEnum state = LifecycleStateEnum.CERTIFICATION_IN_PROGRESS; + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + + result = updateComponentMD(component, modifier, state, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + state, result.right().value()); + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus updateStartCertificationOnGraph(NodeTypeEnum componentType, String componentId, + User modifier, User owner) { + StorageOperationStatus changeRelationLabel = changeRelationLabel(componentType, componentId, owner, + GraphEdgeLabels.STATE, GraphEdgeLabels.LAST_STATE); + if (!changeRelationLabel.equals(StorageOperationStatus.OK)) { + return changeRelationLabel; + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + StorageOperationStatus createUserToResourceRelation = createUserToResourceRelation(componentType, + modifier.getUserId(), componentId, GraphEdgeLabels.STATE, props); + if (!createUserToResourceRelation.equals(StorageOperationStatus.OK)) { + return createUserToResourceRelation; + } + return StorageOperationStatus.OK; + } + + @Override + public Either<? extends Component, StorageOperationStatus> certifyComponent(NodeTypeEnum nodeType, + Component component, User modifier, User currentOwner, boolean inTransaction) { + Either<? extends Component, StorageOperationStatus> result = null; + + try { + String resourceIdBeforeCertify = component.getUniqueId(); + String[] versionParts = component.getVersion().split(VERSION_DELIMETER_REGEXP); + Integer majorVersion = Integer.parseInt(versionParts[0]); + + // update old certified resource + if (majorVersion > 0) { + StorageOperationStatus updateLastCertifiedResource = StorageOperationStatus.OK; + updateLastCertifiedResource = updateLastCertifiedComponent(component, majorVersion); + if (!updateLastCertifiedResource.equals(StorageOperationStatus.OK)) { + return Either.right(updateLastCertifiedResource); + } + } + + // clone the resource + Either<? extends Component, StorageOperationStatus> createResourceResult = Either + .right(StorageOperationStatus.GENERAL_ERROR); + switch (nodeType) { + case Service: + case Resource: + createResourceResult = cloneComponentForCertified(component, modifier, majorVersion); + break; + default: + log.error("component object is with type {} . It's not supported type"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + if (createResourceResult.isRight()) { + log.error("failed to create new resource version for checkout."); + result = createResourceResult; + return createResourceResult; + } + + Component certifiedResource = createResourceResult.left().value(); + + // add rfc relation to preserve follower information + StorageOperationStatus addRfcRelation = addRfcRelationToCertfiedComponent(nodeType, resourceIdBeforeCertify, + certifiedResource.getUniqueId()); + if (!addRfcRelation.equals(StorageOperationStatus.OK)) { + result = Either.right(addRfcRelation); + return result; + } + + result = Either.left(certifiedResource); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + @Override + public Either<Boolean, StorageOperationStatus> deleteOldComponentVersions(NodeTypeEnum nodeType, + String componentName, String uuid, boolean inTransaction) { + + Either<Boolean, StorageOperationStatus> result = null; + ComponentOperation componentOperation = getComponentOperation(nodeType); + + try { + Either<List<Component>, StorageOperationStatus> oldVersionsToDelete = getComponentTempVersions(nodeType, + uuid); + + if (oldVersionsToDelete.isRight()) { + result = Either.right(oldVersionsToDelete.right().value()); + return result; + } + + for (Component resourceToDelete : oldVersionsToDelete.left().value()) { + + Either<Component, StorageOperationStatus> updateResource = componentOperation + .markComponentToDelete(resourceToDelete, inTransaction); + if (updateResource.isRight()) { + result = Either.right(updateResource.right().value()); + return result; + } + } + result = Either.left(true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus addRfcRelationToCertfiedComponent(NodeTypeEnum componentType, + String resourceIdBeforeCertify, String uniqueId) { + + // get user of certification request + UniqueIdData componentV = new UniqueIdData(componentType, resourceIdBeforeCertify); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + Either<GraphRelation, TitanOperationStatus> rfcRelationResponse = titanGenericDao + .getIncomingRelationByCriteria(componentV, GraphEdgeLabels.LAST_STATE, props); + if (rfcRelationResponse.isRight()) { + TitanOperationStatus status = rfcRelationResponse.right().value(); + log.error("failed to find rfc relation for component {}. status=", resourceIdBeforeCertify, status); + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + GraphRelation rfcRelation = rfcRelationResponse.left().value(); + rfcRelation.setTo( + new RelationEndPoint(componentType, GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId)); + + Either<GraphRelation, TitanOperationStatus> createRelationResponse = titanGenericDao + .createRelation(rfcRelation); + if (createRelationResponse.isRight()) { + TitanOperationStatus status = createRelationResponse.right().value(); + log.error("failed to create rfc relation for component {}. status=", uniqueId, status); + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus updateLastCertifiedComponent(Component component, Integer majorVersion) { + + NodeTypeEnum nodeType = component.getComponentType().getNodeType(); + ComponentOperation componentOperation = getComponentOperation(nodeType); + Map<String, Object> additionalQueryParams = null; + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) component).getResourceType(); + additionalQueryParams = new HashMap<String, Object>(); + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + Either<? extends Component, StorageOperationStatus> getLastCertifiedResponse = componentOperation + .getComponentByNameAndVersion(component.getName(), majorVersion + VERSION_DELIMETER + "0", + additionalQueryParams, true); + + if (getLastCertifiedResponse.isRight()) { + log.error("failed to update last certified resource. status={}", getLastCertifiedResponse.right().value()); + return getLastCertifiedResponse.right().value(); + } + + Component lastCertified = getLastCertifiedResponse.left().value(); + lastCertified.setHighestVersion(false); + Either<Component, StorageOperationStatus> updateResource = componentOperation.updateComponent(lastCertified, + true); + if (updateResource.isRight()) { + log.error("failed to update last certified resource. status={}", updateResource.right().value()); + return updateResource.right().value(); + } + return StorageOperationStatus.OK; + } + + private Either<Component, StorageOperationStatus> cloneComponentForCheckout(Component component, + NodeTypeEnum nodeType, User modifier) { + + ComponentOperation componentOperation = getComponentOperation(nodeType); + String prevId = component.getUniqueId(); + // set new version + Either<String, StorageOperationStatus> nextVersion = getNextVersion(component.getVersion()); + if (nextVersion.isRight()) { + return Either.right(nextVersion.right().value()); + } + + // if checkout on certified service - init distribution status back + if (nodeType == NodeTypeEnum.Service && component.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + ((Service) component).setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + } + + String version = nextVersion.left().value(); + component.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + component.setHighestVersion(true); + + // check version of resource does not exist. Note that resource type VF + // can have same name as resource type VFC + Map<String, Object> additionalQueryParams = null; + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) component).getResourceType(); + additionalQueryParams = new HashMap<String, Object>(); + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + String name = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + Either<Component, StorageOperationStatus> alreadyExistResult = componentOperation + .getComponentByNameAndVersion(name, version, additionalQueryParams, true); + if (alreadyExistResult.isLeft()) { + log.debug("Component with name {} and version {} already exist", name, version); + return Either.right(StorageOperationStatus.ENTITY_ALREADY_EXISTS); + + } + + StorageOperationStatus storageOperationStatus = alreadyExistResult.right().value(); + if (storageOperationStatus != StorageOperationStatus.NOT_FOUND) { + log.debug( + "Unexpected error when checking if component with name {} and version {} already exist, error: {}", + name, version, storageOperationStatus); + return Either.right(storageOperationStatus); + } + + Either<Component, StorageOperationStatus> cloneComponentResponse = componentOperation.cloneComponent(component, + version, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, true); + + return cloneComponentResponse; + } + + private Either<String, StorageOperationStatus> getNextVersion(String currVersion) { + String[] versionParts = currVersion.split(VERSION_DELIMETER_REGEXP); + if (versionParts == null || versionParts.length != 2) { + log.error("invalid version {}", currVersion); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Integer minorVersion = Integer.parseInt(versionParts[1]) + 1; + String newVersion = versionParts[0] + VERSION_DELIMETER + minorVersion; + return Either.left(newVersion); + } + + private StorageOperationStatus setRelationForCancelCertification(LifecycleStateEnum nextState, + NodeTypeEnum componentType, String componentId) { + + StorageOperationStatus result = StorageOperationStatus.GENERAL_ERROR; + Map<String, Object> props = new HashMap<String, Object>(); + UniqueIdData componentData = new UniqueIdData(componentType, componentId); + + // delete relation CERTIFICATION_IN_PROGRESS + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either<GraphRelation, TitanOperationStatus> deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation READY_FOR_CERTIFICATION (LAST_STATE) + props.put(GraphPropertiesDictionary.STATE.getProperty(), nextState); + + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + GraphRelation origRelation = deleteResult.left().value(); + + // create relation READY_FOR_CERTIFICATION (STATE) + UserData user = new UserData(); + user.setUserId((String) origRelation.getFrom().getIdValue()); + Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(user, + componentData, GraphEdgeLabels.STATE, origRelation.toGraphMap()); + + if (createRelationResult.isRight()) { + log.error("failed to update last state relation. status={}", createRelationResult.right().value()); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus setRelationForFailCertification(LifecycleStateEnum nextState, + NodeTypeEnum componentType, String componentId) { + + StorageOperationStatus result = null; + Map<String, Object> props = new HashMap<String, Object>(); + UniqueIdData componentData = new UniqueIdData(componentType, componentId); + + // delete relation CERTIFICATION_IN_PROGRESS + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + + Either<GraphRelation, TitanOperationStatus> deleteResult = titanGenericDao + .deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.STATE, props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation READY_FOR_CERTIFICATION + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.READY_FOR_CERTIFICATION); + + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // delete relation NOT_CERTIFIED_CHECKIN (in order to change to STATE) + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + deleteResult = titanGenericDao.deleteIncomingRelationByCriteria(componentData, GraphEdgeLabels.LAST_STATE, + props); + if (deleteResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + + // create new STATE relation NOT_CERTIFIED_CHECKIN + GraphRelation origRelation = deleteResult.left().value(); + UserData user = new UserData(); + user.setUserId((String) origRelation.getFrom().getIdValue()); + Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(user, + componentData, GraphEdgeLabels.STATE, origRelation.toGraphMap()); + + if (createRelationResult.isRight()) { + log.debug("failed to update last state relation"); + result = StorageOperationStatus.INCONSISTENCY; + return result; + } + return StorageOperationStatus.OK; + } + + /** + * update service metadata - lastUpdater and state + * + * @param component + * @param modifier + * @param nextState + * @return + */ + private Either<Component, StorageOperationStatus> updateComponentMD(Component component, User modifier, + LifecycleStateEnum nextState, NodeTypeEnum nodeType, + ComponentParametersView returnedComponentParametersViewFilter) { + + if (returnedComponentParametersViewFilter == null) { + returnedComponentParametersViewFilter = new ComponentParametersView(); + } + + Either<Component, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + component.setLastUpdateDate(null); + component.setLastUpdaterUserId(modifier.getUserId()); + + ComponentOperation componentOperation = getComponentOperation(nodeType); + ComponentParametersView filterParametersView = buildFilterForFetchComponentAfterChangeState(); + log.debug("updateComponentMD::updateComponentFilterResult start"); + result = componentOperation.updateComponentFilterResult(component, true, filterParametersView); + log.debug("updateComponentMD::updateComponentFilterResult end"); + if (result.isRight()) { + log.debug("Failed to update component for certification request, error: {}", result.right().value()); + return result; + } + log.debug("updateComponentMD::getAndUpdateMetadata start"); + // get service MD + Either<ComponentMetadataData, TitanOperationStatus> componentDataResult = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(nodeType), component.getUniqueId(), ComponentMetadataData.class); + if (componentDataResult.isRight()) { + log.debug("failed to get service data from graph"); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(componentDataResult.right().value())); + } + + // set state on resource + ComponentMetadataData componentData = componentDataResult.left().value(); + componentData.getMetadataDataDefinition().setState(nextState.name()); + component.setLifecycleState(nextState); + Either<ComponentMetadataData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(componentData, + ComponentMetadataData.class); + log.debug("updateComponentMD::getAndUpdateMetadata end"); + if (updateNode.isRight()) { + log.error("Failed to update component " + component.getUniqueId() + ". status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + log.debug("updateComponentMD::getAndUpdateMetadata start"); + Either<Object, StorageOperationStatus> serviceAfterChange = componentOperation + .getComponent(component.getUniqueId(), returnedComponentParametersViewFilter, true); + log.debug("updateComponentMD::getAndUpdateMetadata end"); + if (serviceAfterChange.isRight()) { + log.error("Failed to get component " + component.getUniqueId() + " after change. status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + return Either.left((Component) serviceAfterChange.left().value()); + } + + /** + * update resouce metadata - lastUpdater and state + * + * @param resource + * @param modifier + * @param nextState + * @return + */ + private Either<Resource, StorageOperationStatus> updateResourceMD(Resource resource, User modifier, + LifecycleStateEnum nextState) { + + Either<Resource, StorageOperationStatus> result; + resource.setLastUpdateDate(null); + resource.setLastUpdaterUserId(modifier.getUserId()); + + result = resourceOperation.updateResource(resource, true); + if (result.isRight()) { + log.debug("failed to update resource for certification request."); + return result; + } + // get resource MD + Either<ResourceMetadataData, TitanOperationStatus> resourceDataResult = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId(), + ResourceMetadataData.class); + if (resourceDataResult.isRight()) { + log.debug("failed to get resource data from graph"); + return Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceDataResult.right().value())); + } + + // set state on resource + ResourceMetadataData resourceData = resourceDataResult.left().value(); + resourceData.getMetadataDataDefinition().setState(nextState.name()); + resource.setLifecycleState(nextState); + Either<ResourceMetadataData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(resourceData, + ResourceMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource " + resource.getUniqueId() + ". status is " + + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + return Either.left(resource); + } + + private Either<List<Component>, StorageOperationStatus> getComponentTempVersions(NodeTypeEnum nodeType, + String uuid) { + + Either<List<Component>, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + List<Component> componentList = new ArrayList<Component>(); + ComponentOperation componentOperation = getComponentOperation(nodeType); + + Map<String, Object> hasProps = new HashMap<String, Object>(); + Map<String, Object> hasNotProps = new HashMap<String, Object>(); + + createOldVersionsCriteria(nodeType, uuid, hasProps, hasNotProps); + + Either<List<ComponentMetadataData>, TitanOperationStatus> getByCriteria = titanGenericDao + .getByCriteria(nodeType, hasProps, hasNotProps, ComponentMetadataData.class); + + if (getByCriteria.isRight()) { + log.error("failed to get old versions for component, type:{}, id: {}", nodeType, uuid); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(getByCriteria.right().value())); + return result; + } + + List<ComponentMetadataData> oldVersionComponents = getByCriteria.left().value(); + for (ComponentMetadataData component : oldVersionComponents) { + Either<Component, StorageOperationStatus> resourceRes = componentOperation + .getComponent(component.getMetadataDataDefinition().getUniqueId(), true); + if (resourceRes.isRight()) { + result = Either.right(resourceRes.right().value()); + return result; + } else { + componentList.add(resourceRes.left().value()); + } + } + result = Either.left(componentList); + return result; + } + + private void createOldVersionsCriteria(NodeTypeEnum nodeType, String uuid, Map<String, Object> hasProps, + Map<String, Object> hasNotProps) { + + hasProps.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + hasProps.put(GraphPropertiesDictionary.LABEL.getProperty(), nodeType.name().toLowerCase()); + hasNotProps.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + } + + private Either<? extends Component, StorageOperationStatus> updateOldComponentBeforeUndoCheckout( + ComponentOperation componentOperation, Component prevComponent, Component currentComponent, + String previousVersion, NodeTypeEnum nodeType, boolean inTransaction) { + + log.debug("update previous version of component"); + Map<String, Object> additionalQueryParams = new HashMap<String, Object>(); + + if (nodeType == NodeTypeEnum.Resource) { + ResourceTypeEnum resourceType = ((Resource) currentComponent).getResourceType(); + + additionalQueryParams.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), resourceType.name()); + } + ComponentMetadataDataDefinition metadataDataDefinition = currentComponent.getComponentMetadataDefinition() + .getMetadataDataDefinition(); + Either<? extends Component, StorageOperationStatus> getOlderCompResult = componentOperation + .getComponentByNameAndVersion(metadataDataDefinition.getName(), previousVersion, additionalQueryParams, + true); + + // if previous version exist - set it as current version + if (getOlderCompResult.isRight()) { + if (StorageOperationStatus.NOT_FOUND.equals(getOlderCompResult.right().value())) { + log.debug("No components by name and version : {} {}", metadataDataDefinition.getName(), previousVersion); + log.debug("Name may have changed, since the version isn't certified try to fetch by UUID {}", metadataDataDefinition.getUUID()); + additionalQueryParams.clear(); + additionalQueryParams.put(GraphPropertiesDictionary.UUID.getProperty(), + metadataDataDefinition.getUUID()); + additionalQueryParams.put(GraphPropertiesDictionary.VERSION.getProperty(), previousVersion); + + Either<List<ComponentMetadataData>, TitanOperationStatus> byUUID = titanGenericDao + .getByCriteria(nodeType, additionalQueryParams, ComponentMetadataData.class); + if (byUUID.isRight()) { + log.debug("Failed to fetch by UUID {}", metadataDataDefinition.getUUID()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byUUID.right().value())); + } + String prevVersionId = (String) byUUID.left().value().get(0).getUniqueId(); + Either<? extends Component, StorageOperationStatus> component = componentOperation + .getComponent(prevVersionId, inTransaction); + if (component.isRight()) { + log.debug("Failed to fetch previous component by ID {}", prevVersionId); + return Either.right(component.right().value()); + } + prevComponent = component.left().value(); + } else { + log.error("failed to find previous version. status={} ", getOlderCompResult.right().value()); + return getOlderCompResult; + } + } else { + prevComponent = getOlderCompResult.left().value(); + } + + // if last resource is certified - don't touch it. + if (prevComponent.getVersion().endsWith(".0")) { + return Either.left(prevComponent); + } + + prevComponent.setHighestVersion(true); + Either<Component, StorageOperationStatus> updateCompResult = componentOperation.updateComponent(prevComponent, + inTransaction); + if (updateCompResult.isRight()) { + log.debug("failed to update prev version of component"); + return updateCompResult; + } + + User user = new User(); + user.setUserId(prevComponent.getLastUpdaterUserId()); + StorageOperationStatus changeStateRelation = changeStateRelation(nodeType, prevComponent.getUniqueId(), user, + GraphEdgeLabels.LAST_STATE, GraphEdgeLabels.STATE); + if (!changeStateRelation.equals(StorageOperationStatus.OK)) { + return Either.right(changeStateRelation); + } + + return Either.left(prevComponent); + } + + private StorageOperationStatus changeStateRelation(NodeTypeEnum nodeType, String componentId, User currentOwner, + GraphEdgeLabels from, GraphEdgeLabels to) { + UniqueIdData componentData = new UniqueIdData(nodeType, componentId); + UserData userData = new UserData(); + userData.setUserId(currentOwner.getUserId()); + Either<GraphRelation, TitanOperationStatus> replaceRelationLabelResult = titanGenericDao + .replaceRelationLabel(userData, componentData, from, to); + if (replaceRelationLabelResult.isRight()) { + TitanOperationStatus titanStatus = replaceRelationLabelResult.right().value(); + log.error("failed to replace label from {} to {}. status = {}", from, to, titanStatus); + StorageOperationStatus storageStatus = StorageOperationStatus.INCONSISTENCY; + if (!titanStatus.equals(TitanOperationStatus.INVALID_ID)) { + storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + return storageStatus; + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeUserToResourceRelation(NodeTypeEnum componentType, String idFrom, String idTo, + GraphEdgeLabels label) { + + UniqueIdData componentV = new UniqueIdData(componentType, idTo); + UserData userV = new UserData(); + userV.setUserId(idFrom); + // delete relation + Either<GraphRelation, TitanOperationStatus> deleteRelationResult = titanGenericDao.deleteRelation(userV, + componentV, label); + if (deleteRelationResult.isRight()) { + log.error("failed to delete relation. status={}", deleteRelationResult.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteRelationResult.right().value()); + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus createUserToResourceRelation(NodeTypeEnum componentType, String idFrom, String idTo, + GraphEdgeLabels label, Map<String, Object> props) { + + UniqueIdData componentV = new UniqueIdData(componentType, idTo); + UserData userV = new UserData(); + userV.setUserId(idFrom); + // create relation + Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(userV, + componentV, label, props); + if (createRelationResult.isRight()) { + log.error("failed to create relation. status={}", createRelationResult.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(createRelationResult.right().value()); + } + return StorageOperationStatus.OK; + } + + @Override + public Either<? extends Component, StorageOperationStatus> cancelOrFailCertification(NodeTypeEnum nodeType, + Component component, User modifier, User owner, LifecycleStateEnum nextState, boolean inTransaction) { + + Either<? extends Component, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + ComponentParametersView componentParametersView = buildFilterForFetchComponentAfterChangeState(); + result = updateComponentMD(component, modifier, nextState, nodeType, componentParametersView); + if (result.isRight()) { + log.debug("Couldn't set lifecycle for component {} to state {}, error: {}", component.getUniqueId(), + nextState, result.right().value()); + return result; + } + StorageOperationStatus status = StorageOperationStatus.OK; + // cancel certification process + if (nextState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + status = setRelationForCancelCertification(nextState, nodeType, component.getUniqueId()); + + } // fail certification + else if (nextState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN)) { + status = setRelationForFailCertification(nextState, nodeType, component.getUniqueId()); + } + + if (!status.equals(StorageOperationStatus.OK)) { + result = Either.right(status); + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java new file mode 100644 index 0000000000..55531fec79 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import org.openecomp.sdc.be.dao.neo4j.Neo4jOperationStatus; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +public class Neo4jStatusConverter { + + public static StorageOperationStatus convertNeo4jStatusToStorageStatus(Neo4jOperationStatus neo4jStatus) { + + if (neo4jStatus == null) { + return StorageOperationStatus.GENERAL_ERROR; + } + + switch (neo4jStatus) { + + case OK: + return StorageOperationStatus.OK; + + case NOT_CONNECTED: + return StorageOperationStatus.CONNECTION_FAILURE; + + case NOT_AUTHORIZED: + return StorageOperationStatus.PERMISSION_ERROR; + + case HTTP_PROTOCOL_ERROR: + return StorageOperationStatus.HTTP_PROTOCOL_ERROR; + case DB_NOT_AVAILABLE: + return StorageOperationStatus.STORAGE_NOT_AVAILABLE; + case DB_READ_ONLY: + return StorageOperationStatus.READ_ONLY_STORAGE; + case BAD_REQUEST: + return StorageOperationStatus.BAD_REQUEST; + case LEGACY_INDEX_ERROR: + return StorageOperationStatus.STORAGE_LEGACY_INDEX_ERROR; + case SCHEMA_ERROR: + return StorageOperationStatus.SCHEMA_ERROR; + case TRANSACTION_ERROR: + return StorageOperationStatus.TRANSACTION_ERROR; + case EXECUTION_FAILED: + return StorageOperationStatus.EXEUCTION_FAILED; + case ENTITY_ALREADY_EXIST: + return StorageOperationStatus.ENTITY_ALREADY_EXISTS; + case WRONG_INPUT: + return StorageOperationStatus.BAD_REQUEST; + case GENERAL_ERROR: + return StorageOperationStatus.GENERAL_ERROR; + case NOT_SUPPORTED: + return StorageOperationStatus.OPERATION_NOT_SUPPORTED; + case NOT_FOUND: + return StorageOperationStatus.NOT_FOUND; + + default: + return StorageOperationStatus.GENERAL_ERROR; + } + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java new file mode 100644 index 0000000000..a7f8275064 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java @@ -0,0 +1,190 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.io.File; +import java.io.FileFilter; +import java.io.IOException; +import java.nio.file.Files; +import java.util.Map; +import java.util.Properties; + +import javax.annotation.PostConstruct; + +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.config.Configuration.OnboardingConfig; +import org.openecomp.sdc.be.dao.rest.HttpRestClient; +import org.openecomp.sdc.be.dao.rest.RestConfigurationInfo; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.rest.api.RestResponseAsByteArray; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("onboarding-client") +public class OnboardingClient { + + private static Logger log = LoggerFactory.getLogger(OnboardingClient.class.getName()); + + private HttpRestClient httpRestClient = null; + + private static Properties downloadCsarHeaders = new Properties(); + + static { + downloadCsarHeaders.put("Accept", "application/octet-stream"); + } + + public OnboardingClient() { + super(); + } + + public static void main(String[] args) { + + OnboardingClient csarOperation = new OnboardingClient(); + csarOperation.init(); + + String csarUuid = "70025CF6081B489CA7B1CBA583D5278D"; + Either<Map<String, byte[]>, StorageOperationStatus> csar = csarOperation.getCsar(csarUuid, null); + System.out.println(csar.left().value()); + + } + + @PostConstruct + public void init() { + + // TODO: read connection configuration from OnboardingConfig + // onboardingConfig = + // ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding(); + + RestConfigurationInfo restConfigurationInfo = new RestConfigurationInfo(); + httpRestClient = new HttpRestClient(restConfigurationInfo); + + if (false == httpRestClient.isInitialized()) { + BeEcompErrorManager.getInstance().logInternalFlowError("InitializeRestClient", "Failed to initialize rest client", ErrorSeverity.FATAL); + httpRestClient = null; + } + + } + + // Mock returning a file from the file system until we have API from onboarding + public Either<Map<String, byte[]>, StorageOperationStatus> getMockCsar(String csarUuid) { + File dir = new File("/var/tmp/mockCsar"); + FileFilter fileFilter = new WildcardFileFilter("*.csar"); + File[] files = dir.listFiles(fileFilter); + for (int i = 0; i < files.length; i++) { + File csar = files[i]; + if (csar.getName().startsWith(csarUuid)) { + log.debug("Found CSAR file {} matching the passed csarUuid {}", csar.getAbsolutePath(), csarUuid); + byte[] data; + try { + data = Files.readAllBytes(csar.toPath()); + } catch (IOException e) { + log.debug("Error reading mock file for CSAR, error: {}", e); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Map<String, byte[]> readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } + } + log.debug("Couldn't find mock file for CSAR starting with {}", csarUuid); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + public Either<Map<String, byte[]>, StorageOperationStatus> getCsar(String csarUuid, String userId) { + + if (httpRestClient == null) { + BeEcompErrorManager.getInstance().logInternalFlowError("RestClient", "Rest Client could not be initialized", ErrorSeverity.ERROR); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + String url = buildDownloadCsarUrl() + "/" + csarUuid; + + Properties headers = new Properties(); + if (downloadCsarHeaders != null) { + downloadCsarHeaders.forEach((k, v) -> headers.put(k, v)); + } + + if (userId != null) { + headers.put(Constants.USER_ID_HEADER, userId); + } + + log.debug("Url for downloading csar is {}. Headers are {}", url, headers); + + RestResponseAsByteArray restResponse = httpRestClient.doGetAsByteArray(url, headers); + log.debug("After fetching csar {}. Http return code is {}", csarUuid, restResponse.getHttpStatusCode()); + + switch (restResponse.getHttpStatusCode()) { + case HttpStatus.SC_OK: + byte[] data = restResponse.getResponse(); + if (data != null && data.length > 0) { + Map<String, byte[]> readZip = ZipUtil.readZip(data); + return Either.left(readZip); + } else { + log.debug("Data received from rest is null or empty"); + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + case HttpStatus.SC_NOT_FOUND: + return Either.right(StorageOperationStatus.CSAR_NOT_FOUND); + + default: + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + } + + public HttpRestClient getHttpRestClient() { + return httpRestClient; + } + + public void setHttpRestClient(HttpRestClient httpRestClient) { + this.httpRestClient = httpRestClient; + } + + /** + * Build the url for download CSAR + * + * E.g., http://1.2.3.4:8181/onboarding-api/v1.0/vendor-software-products/packages/ + * + * @return + */ + public String buildDownloadCsarUrl() { + + OnboardingConfig onboardingConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getOnboarding(); + + String protocol = onboardingConfig.getProtocol(); + String host = onboardingConfig.getHost(); + Integer port = onboardingConfig.getPort(); + String uri = onboardingConfig.getDownloadCsarUri(); + + String getCsarUrl = protocol + "://" + host + ":" + port + uri; + + return getCsarUrl; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java new file mode 100644 index 0000000000..d085c242e8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java @@ -0,0 +1,230 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PolicyTypeDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IPolicyTypeOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.PolicyTypeData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("policy-type-operation") +public class PolicyTypeOperation extends AbstractOperation implements IPolicyTypeOperation { + + private static final String CREATE_FLOW_CONTEXT = "CreatePolicyType"; + private static final String GET_FLOW_CONTEXT = "GetPolicyType"; + + @Resource + private PropertyOperation propertyOperation; + + public PolicyTypeOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(PolicyTypeOperation.class.getName()); + + @Override + public Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String policyTypeName) { + return getLatestPolicyTypeByType(policyTypeName, false); + } + + private Either<PolicyTypeDefinition, StorageOperationStatus> getLatestPolicyTypeByType(String type, + boolean inTransaction) { + Map<String, Object> mapCriteria = new HashMap<>(); + mapCriteria.put(GraphPropertiesDictionary.TYPE.getProperty(), type); + mapCriteria.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + return getPolicyTypeByCriteria(type, mapCriteria, inTransaction); + } + + @Override + public Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyType) { + return addPolicyType(policyType, false); + } + + @Override + public Either<PolicyTypeDefinition, StorageOperationStatus> addPolicyType(PolicyTypeDefinition policyTypeDef, + boolean inTransaction) { + + Either<PolicyTypeDefinition, StorageOperationStatus> result = null; + + try { + + Either<PolicyTypeData, TitanOperationStatus> eitherStatus = addPolicyTypeToGraph(policyTypeDef); + + if (eitherStatus.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedCreateNodeError(CREATE_FLOW_CONTEXT, + policyTypeDef.getType(), eitherStatus.right().value().name()); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + + } else { + PolicyTypeData policyTypeData = eitherStatus.left().value(); + + String uniqueId = policyTypeData.getUniqueId(); + Either<PolicyTypeDefinition, StorageOperationStatus> policyTypeRes = this.getPolicyType(uniqueId, true); + + if (policyTypeRes.isRight()) { + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError(GET_FLOW_CONTEXT, + policyTypeDef.getType(), eitherStatus.right().value().name()); + } + + result = policyTypeRes; + + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + + } + + private Either<PolicyTypeData, TitanOperationStatus> addPolicyTypeToGraph(PolicyTypeDefinition policyTypeDef) { + log.debug("Got policy type {}", policyTypeDef); + + String ptUniqueId = UniqueIdBuilder.buildPolicyTypeUid(policyTypeDef.getType(), policyTypeDef.getVersion()); + + PolicyTypeData policyTypeData = buildPolicyTypeData(policyTypeDef, ptUniqueId); + + log.debug("Before adding policy type to graph. policyTypeData = {}", policyTypeData); + + Either<PolicyTypeData, TitanOperationStatus> eitherPolicyTypeData = titanGenericDao.createNode(policyTypeData, + PolicyTypeData.class); + log.debug("After adding policy type to graph. status is = {}", eitherPolicyTypeData); + + if (eitherPolicyTypeData.isRight()) { + TitanOperationStatus operationStatus = eitherPolicyTypeData.right().value(); + log.error("Failed to add policy type {} to graph. Status is {}", policyTypeDef.getType(), operationStatus); + return Either.right(operationStatus); + } + + PolicyTypeData resultCTD = eitherPolicyTypeData.left().value(); + List<PropertyDefinition> properties = policyTypeDef.getProperties(); + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToPolicyType = propertyOperation + .addPropertiesToElementType(resultCTD.getUniqueId(), NodeTypeEnum.PolicyType, properties); + if (addPropertiesToPolicyType.isRight()) { + log.error("Failed add properties {} to policy {}", properties, policyTypeDef.getType()); + return Either.right(addPropertiesToPolicyType.right().value()); + } + + return Either.left(eitherPolicyTypeData.left().value()); + } + + public Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyTypeByCriteria(String type, + Map<String, Object> properties, boolean inTransaction) { + Either<PolicyTypeDefinition, StorageOperationStatus> result = null; + try { + if (type == null || type.isEmpty()) { + log.error("type is empty"); + result = Either.right(StorageOperationStatus.INVALID_ID); + return result; + } + + Either<List<PolicyTypeData>, TitanOperationStatus> eitherPolicyData = titanGenericDao + .getByCriteria(NodeTypeEnum.PolicyType, properties, PolicyTypeData.class); + if (eitherPolicyData.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherPolicyData.right().value())); + } else { + PolicyTypeDataDefinition dataDefinition = eitherPolicyData.left().value().stream() + .map(e -> e.getPolicyTypeDataDefinition()).findFirst().get(); + result = getPolicyType(dataDefinition.getUniqueId(), inTransaction); + } + + return result; + + } finally { + handleTransactionCommitRollback(inTransaction, result); + } + } + + @Override + public Either<PolicyTypeDefinition, StorageOperationStatus> getPolicyType(String uniqueId, boolean inTransaction) { + Function<String, Either<PolicyTypeDefinition, TitanOperationStatus>> policyTypeGetter = uId -> getPolicyTypeByUid( + uId); + return getElementType(policyTypeGetter, uniqueId, inTransaction); + + } + + private Either<PolicyTypeDefinition, TitanOperationStatus> getPolicyTypeByUid(String uniqueId) { + Either<PolicyTypeDefinition, TitanOperationStatus> result = null; + + Either<PolicyTypeData, TitanOperationStatus> eitherPolicyTypeData = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PolicyType), uniqueId, PolicyTypeData.class); + + if (eitherPolicyTypeData.isRight()) { + TitanOperationStatus status = eitherPolicyTypeData.right().value(); + log.debug("Policy type {} cannot be found in graph. Status is {}", uniqueId, status); + return Either.right(status); + } + + PolicyTypeData policyTypeData = eitherPolicyTypeData.left().value(); + PolicyTypeDefinition policyTypeDefinition = new PolicyTypeDefinition( + policyTypeData.getPolicyTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = propertyOperation.fillProperties(uniqueId, + propList -> policyTypeDefinition.setProperties(propList)); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of policy type {}", uniqueId); + return Either.right(propertiesStatus); + } + + result = Either.left(policyTypeDefinition); + + return result; + } + + private PolicyTypeData buildPolicyTypeData(PolicyTypeDefinition policyTypeDefinition, String ptUniqueId) { + + PolicyTypeData policyTypeData = new PolicyTypeData(policyTypeDefinition); + + policyTypeData.getPolicyTypeDataDefinition().setUniqueId(ptUniqueId); + Long creationDate = policyTypeData.getPolicyTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + + policyTypeData.getPolicyTypeDataDefinition().setCreationTime(creationDate); + policyTypeData.getPolicyTypeDataDefinition().setModificationTime(creationDate); + return policyTypeData; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java new file mode 100644 index 0000000000..2a8192421b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java @@ -0,0 +1,1067 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; +import java.util.Set; + +import com.thinkaurelius.titan.core.TitanTransaction; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.category.GroupingDataDefinition; +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ProductMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.*; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IProductOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ProductMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.GroupingData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanGraph; + +import fj.data.Either; + +@org.springframework.stereotype.Component("product-operation") +public class ProductOperation extends ComponentOperation implements IProductOperation { + + private static Logger log = LoggerFactory.getLogger(ProductOperation.class.getName()); + + public ProductOperation() { + log.debug("ProductOperation created"); + } + + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getProductMetadataDataFromProduct((Product) component); + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getProduct(id, inTransaction); + } + + // public <T> Either<T, StorageOperationStatus> getComponent_tx(String id, + // boolean inTransaction) { + // return (Either<T, StorageOperationStatus>) getProduct_tx(id, + // inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + protected <T> Either<T, StorageOperationStatus> getComponentByNameAndVersion(String name, String version, + Map<String, Object> additionalParams, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getByNamesAndVersion(GraphPropertiesDictionary.NAME.getProperty(), + name, version, additionalParams, inTransaction); + } + + @Override + public <T> Either<T, StorageOperationStatus> getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Product, inTransaction); + } + + @Override + public <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, + boolean inTransaction) { + return getFilteredComponents(filters, inTransaction, NodeTypeEnum.Product); + } + + private Product convertProductDataToProduct(ProductMetadataData productData) { + ProductMetadataDefinition productMetadataDefinition = new ProductMetadataDefinition( + (ProductMetadataDataDefinition) productData.getMetadataDataDefinition()); + + Product product = new Product(productMetadataDefinition); + + return product; + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> updateComponent(T component, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) updateComponent((Component) component, inTransaction, + titanGenericDao, Product.class, NodeTypeEnum.Product); + } + + @SuppressWarnings("unchecked") + @Override + public Either<Component, StorageOperationStatus> deleteComponent(String id, boolean inTransaction) { + return (Either<Component, StorageOperationStatus>) (Either<?, StorageOperationStatus>) deleteProduct(id, + inTransaction); + } + + @Override + public Either<List<ArtifactDefinition>, StorageOperationStatus> getAdditionalArtifacts(String resourceId, + boolean recursively, boolean inTransaction) { + // TODO Auto-generated method stub + return null; + } + + @SuppressWarnings("unchecked") + @Override + public <T extends org.openecomp.sdc.be.model.Component> Either<T, StorageOperationStatus> getComponent(String id, + Class<T> clazz) { + return (Either<T, StorageOperationStatus>) getProduct(id, false); + } + + @Override + /** + * Deletes the product node + */ + public Either<Product, StorageOperationStatus> deleteProduct(String productId, boolean inTransaction) { + + Either<Product, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + Either<ProductMetadataData, TitanOperationStatus> productNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Product), productId, ProductMetadataData.class); + if (productNode.isRight()) { + TitanOperationStatus status = productNode.right().value(); + log.error("Failed to find product {}. Status is {}", productId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Either<Product, StorageOperationStatus> productRes = getProduct(productId, true); + if (productRes.isRight()) { + StorageOperationStatus status = productRes.right().value(); + log.error("Failed to find product {}", productId, status); + result = Either.right(status); + return result; + } + Product product = productRes.left().value(); + + Either<List<ComponentInstance>, StorageOperationStatus> deleteAllInstancesRes = componentInstanceOperation + .deleteAllComponentInstances(productId, NodeTypeEnum.Product, true); + log.debug("After deleting instances under product {}. Result is {}", productId, deleteAllInstancesRes); + if (deleteAllInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllInstancesRes.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + log.error("Failed to delete instances under product {}. Status is {}", productId, status); + result = Either.right(status); + return result; + } + } + + Either<ProductMetadataData, TitanOperationStatus> deleteProductNodeRes = titanGenericDao + .deleteNode(productNode.left().value(), ProductMetadataData.class); + if (deleteProductNodeRes.isRight()) { + TitanOperationStatus status = deleteProductNodeRes.right().value(); + log.error("Failed to delete product node {}. Status is {}", productId, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + result = Either.left(product); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("deleteProduct operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteProduct operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<Product>, StorageOperationStatus> getProductCatalogData(boolean inTransaction) { + + long start = System.currentTimeMillis(); + try { + /* + * Map<String, Object> propertiesToMatch = new HashMap<>(); + * + * propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty + * (), LifecycleStateEnum.CERTIFIED.name()); + * Either<List<ProductMetadataData>, TitanOperationStatus> + * lastVersionNodes = getLastVersion(NodeTypeEnum.Product, + * propertiesToMatch, ProductMetadataData.class); if + * (lastVersionNodes.isRight() && lastVersionNodes.right().value() + * != TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (lastVersionNodes.right().value())); } List<ProductMetadataData> + * notCertifiedHighest = (lastVersionNodes.isLeft() ? + * lastVersionNodes.left().value() : new + * ArrayList<ProductMetadataData>()); + * + * propertiesToMatch.put(GraphPropertiesDictionary. + * IS_HIGHEST_VERSION.getProperty(), true); + * Either<List<ProductMetadataData>, TitanOperationStatus> + * componentsNodes = + * titanGenericDao.getByCriteria(NodeTypeEnum.Product, + * propertiesToMatch, ProductMetadataData.class); if + * (componentsNodes.isRight() && componentsNodes.right().value() != + * TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (componentsNodes.right().value())); } List<ProductMetadataData> + * certifiedHighest = (componentsNodes.isLeft() ? + * componentsNodes.left().value() : new + * ArrayList<ProductMetadataData>()); Set<String> names = new + * HashSet<String>(); for (ProductMetadataData data : + * notCertifiedHighest) { String name = + * data.getMetadataDataDefinition().getName(); names.add(name); } + * + * for (ProductMetadataData data : certifiedHighest) { String + * productName = data.getMetadataDataDefinition().getName(); if + * (!names.contains(productName)) { notCertifiedHighest.add(data); } + * } + */ + Either<List<ProductMetadataData>, TitanOperationStatus> listOfHighestComponents = this + .getListOfHighestComponents(NodeTypeEnum.Product, ProductMetadataData.class); + if (listOfHighestComponents.isRight() + && listOfHighestComponents.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(listOfHighestComponents.right().value())); + } + + List<ProductMetadataData> notCertifiedHighest = listOfHighestComponents.left().value(); + + List<Product> result = new ArrayList<>(); + + if (notCertifiedHighest != null && false == notCertifiedHighest.isEmpty()) { + + // fetch from cache + long startFetchAllFromCache = System.currentTimeMillis(); + + Map<String, Long> components = notCertifiedHighest.stream() + .collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), + p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFromCacheForCatalog = this + .getComponentsFromCacheForCatalog(components, ComponentTypeEnum.PRODUCT); + if (componentsFromCacheForCatalog.isLeft()) { + ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFromCacheForCatalog.left() + .value(); + List<Component> list = immutablePair.getLeft(); + if (list != null) { + for (Component component : list) { + result.add((Product) component); + } + List<String> addedUids = list.stream() + .map(p -> p.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream() + .filter(p -> false == addedUids.contains(p.getMetadataDataDefinition().getUniqueId())) + .collect(Collectors.toList()); + } + } + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog products metadata from cache took {} ms", + (endFetchAllFromCache - startFetchAllFromCache)); + log.debug("The number of products added to catalog from cache is {}", result.size()); + + log.debug("The number of products needed to be fetch as light component is {}", + notCertifiedHighest.size()); + + for (ProductMetadataData data : notCertifiedHighest) { + Either<Product, StorageOperationStatus> component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get product for id = {}, error : {}. skip product", data.getUniqueId(), + component.right().value()); + } else { + // get all versions + Product product = component.left().value(); + // setAllVersions(product); + + result.add(product); + } + } + } + return Either.left(result); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("Fetch all catalog products took {} ms", (System.currentTimeMillis() - start)); + } + } + + @Override + public Either<Product, StorageOperationStatus> createProduct(Product product) { + return createProduct(product, false); + } + + @Override + public Either<Product, StorageOperationStatus> createProduct(Product product, boolean inTransaction) { + Either<Product, StorageOperationStatus> result = null; + + try { + + ProductMetadataData productData = getProductMetadataDataFromProduct(product); + addComponentInternalFields(productData); + String uniqueId = (String) productData.getUniqueId(); + generateUUID(product); + + String userId = product.getCreatorUserId(); + + Either<UserData, TitanOperationStatus> findUser = findUser(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. status is {}", userId, status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + UserData creatorUserData = findUser.left().value(); + UserData updaterUserData = creatorUserData; + String updaterUserId = product.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUser(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user {} in the graph. status is {}", userId, status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterUserData = findUser.left().value(); + } + } + + log.trace("Creating tags for product {}", uniqueId); + StorageOperationStatus storageOperationStatus = createTagsForComponent(product); + if (storageOperationStatus != StorageOperationStatus.OK) { + return Either.right(storageOperationStatus); + } + + log.trace("Finding groupings for product {}", uniqueId); + Either<List<GroupingData>, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, product); + if (findGroupingsForComponent.isRight()) { + return Either.right(findGroupingsForComponent.right().value()); + } + List<GroupingData> groupingDataToAssociate = findGroupingsForComponent.left().value(); + + log.debug("try to create product node on graph for id {}", uniqueId); + Either<ProductMetadataData, TitanOperationStatus> createNode = titanGenericDao.createNode(productData, + ProductMetadataData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating product data node {}. Status returned is {}", productData, + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("product node created on graph for id {}", productData.getUniqueId()); + + TitanOperationStatus associateMetadata = associateMetadataToComponent(productData, creatorUserData, + updaterUserData, null, null); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + + TitanOperationStatus associateCategories = associateCategoriesToProduct(productData, + groupingDataToAssociate); + if (associateCategories != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateCategories)); + return result; + } + + result = getProduct(uniqueId, true); + if (result.isRight()) { + log.error("Cannot get full product from the graph. status is {}", result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Product retrieved is {}", json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus associateCategoriesToProduct(ProductMetadataData productData, + List<GroupingData> groupingDataToAssociate) { + for (GroupingData groupingData : groupingDataToAssociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.CATEGORIZED_TO; + Either<GraphRelation, TitanOperationStatus> result = titanGenericDao.createRelation(productData, + groupingData, groupingLabel, null); + log.debug("After associating grouping {} to product {}. Edge type is {}", groupingData, productData, + groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings associated succesfully to product {}", productData); + return TitanOperationStatus.OK; + } + + private TitanOperationStatus dissociateCategoriesFromProduct(ProductMetadataData productData, + List<GroupingData> groupingDataToDissociate) { + for (GroupingData groupingData : groupingDataToDissociate) { + GraphEdgeLabels groupingLabel = GraphEdgeLabels.CATEGORIZED_TO; + Either<GraphRelation, TitanOperationStatus> result = titanGenericDao.deleteRelation(productData, + groupingData, groupingLabel); + log.debug("After dissociating grouping {} from product {}. Edge type is {}", groupingData, productData, + groupingLabel); + if (result.isRight()) { + return result.right().value(); + } + } + log.trace("All groupings dissociated succesfully from product {}", productData); + return TitanOperationStatus.OK; + } + + private Either<Product, StorageOperationStatus> getProduct(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getProduct(uniqueId, componentParametersView, inTransaction); + } + + private Either<Product, StorageOperationStatus> getProduct(String uniqueId, + ComponentParametersView componentParametersView, boolean inTransaction) { + Product product = null; + Either<Product, StorageOperationStatus> result = null; + try { + + NodeTypeEnum productNodeType = NodeTypeEnum.Product; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Service; + + Either<ProductMetadataData, StorageOperationStatus> getComponentByLabel = getComponentByLabelAndId(uniqueId, + productNodeType, ProductMetadataData.class); + if (getComponentByLabel.isRight()) { + result = Either.right(getComponentByLabel.right().value()); + return result; + } + ProductMetadataData productData = getComponentByLabel.left().value(); + + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either<Product, ActionStatus> componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, + productData, componentParametersView, Product.class, ComponentTypeEnum.PRODUCT); + if (componentFromCacheIfUpToDate.isLeft()) { + Product cachedProduct = componentFromCacheIfUpToDate.left().value(); + log.debug("Product {} with uid {} was fetched from cache.", cachedProduct.getName(), + cachedProduct.getUniqueId()); + return Either.left(cachedProduct); + } + + product = convertProductDataToProduct(productData); + + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setComponentCreatorFromGraph(product, uniqueId, productNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + status = setComponentLastModifierFromGraph(product, uniqueId, productNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + if (false == componentParametersView.isIgnoreComponentInstances() + || false == componentParametersView.isIgnoreComponentInstancesProperties() + || false == componentParametersView.isIgnoreCapabilities() + || false == componentParametersView.isIgnoreRequirements()) { + status = setComponentInstancesFromGraph(uniqueId, product, productNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreCapabilities()) { + status = setCapabilitiesFromGraph(uniqueId, product, NodeTypeEnum.Product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreRequirements()) { + status = setRequirementsFromGraph(uniqueId, product, NodeTypeEnum.Product); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(product); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + result = Either.left(product); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + + // private Either<Product, StorageOperationStatus> getProduct_tx(String + // uniqueId, boolean inTransaction) { + // Product product = null; + // Either<Product, StorageOperationStatus> result = null; + // try { + // + // NodeTypeEnum productNodeType = NodeTypeEnum.Product; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Service; + // + // Either<ProductMetadataData, StorageOperationStatus> getComponentByLabel = + // getComponentByLabelAndId_tx(uniqueId, productNodeType, + // ProductMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ProductMetadataData productData = getComponentByLabel.left().value(); + // product = convertProductDataToProduct(productData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(product, + // uniqueId, productNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(product, uniqueId, + // productNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, product, + // productNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, product, + // NodeTypeEnum.Product); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, product, + // NodeTypeEnum.Product);; + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // + // status = setAllVersions(product); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(product); + // return result; + // + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + private TitanOperationStatus setAllVersions(Product product) { + Either<Map<String, String>, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Product, + product.getVersion(), product, ProductMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + product.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + private Either<Product, StorageOperationStatus> sendError(TitanOperationStatus status, + StorageOperationStatus statusIfNotFound) { + Either<Product, StorageOperationStatus> result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component component) { + Product product = (Product) component; + // Building the cat->subcat->grouping triples + Either<List<ImmutablePair<GroupingData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Product), product.getUniqueId(), + GraphEdgeLabels.CATEGORIZED_TO, NodeTypeEnum.ProductGrouping, GroupingData.class); + if (childrenNodes.isRight()) { + if (childrenNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Error when finding groupings for this product, error {}", childrenNodes.right().value()); + return childrenNodes.right().value(); + } else { + log.debug("No groupings found for this product - this might be normal"); + return TitanOperationStatus.OK; + } + } + Map<CategoryDefinition, Map<SubCategoryDefinition, List<GroupingDefinition>>> categoriesDataStructure = new HashMap<>(); + + List<ImmutablePair<GroupingData, GraphEdge>> valueList = childrenNodes.left().value(); + for (ImmutablePair<GroupingData, GraphEdge> groupPair : valueList) { + GroupingData groupingData = groupPair.getLeft(); + Either<ImmutablePair<SubCategoryData, GraphEdge>, TitanOperationStatus> parentSubCat = titanGenericDao + .getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ProductGrouping), + (String) groupingData.getUniqueId(), GraphEdgeLabels.GROUPING, + NodeTypeEnum.ProductSubcategory, SubCategoryData.class); + if (parentSubCat.isRight()) { + log.debug("Cannot find subcategory for grouping {}", groupingData.getUniqueId()); + return parentSubCat.right().value(); + } + SubCategoryData subCatData = parentSubCat.left().value().getLeft(); + Either<ImmutablePair<CategoryData, GraphEdge>, TitanOperationStatus> parentCat = titanGenericDao + .getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ProductSubcategory), + (String) subCatData.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY, + NodeTypeEnum.ProductCategory, CategoryData.class); + if (parentCat.isRight()) { + log.debug("Cannot find category for subcategory {}", subCatData.getUniqueId()); + return parentCat.right().value(); + } + + // Building data structure of categories hierarchy + CategoryDataDefinition categoryDefinition = parentCat.left().value().getLeft().getCategoryDataDefinition(); + SubCategoryDataDefinition subDefinition = subCatData.getSubCategoryDataDefinition(); + GroupingDataDefinition groupingDefinition = groupingData.getGroupingDataDefinition(); + + CategoryDefinition categoryDef = new CategoryDefinition(categoryDefinition); + SubCategoryDefinition subDef = new SubCategoryDefinition(subDefinition); + GroupingDefinition groupingDef = new GroupingDefinition(groupingDefinition); + + if (log.isDebugEnabled()) { + log.debug("Found category {} -> subcategory {} -> grouping {} for product {}", + categoryDefinition.getUniqueId(), subCatData.getUniqueId(), groupingData.getUniqueId(), + product.getUniqueId()); + } + Map<SubCategoryDefinition, List<GroupingDefinition>> subMap = categoriesDataStructure.get(categoryDef); + if (subMap == null) { + subMap = new HashMap<>(); + categoriesDataStructure.put(categoryDef, subMap); + } + List<GroupingDefinition> groupList = subMap.get(subDef); + if (groupList == null) { + groupList = new ArrayList<>(); + subMap.put(subDef, groupList); + } + groupList.add(groupingDef); + } + convertToCategoriesList(product, categoriesDataStructure); + return TitanOperationStatus.OK; + } + + private void convertToCategoriesList(Product product, + Map<CategoryDefinition, Map<SubCategoryDefinition, List<GroupingDefinition>>> categoriesDataStructure) { + List<CategoryDefinition> categoryDataList = product.getCategories(); + if (categoryDataList == null) { + categoryDataList = new ArrayList<CategoryDefinition>(); + } + for (Entry<CategoryDefinition, Map<SubCategoryDefinition, List<GroupingDefinition>>> triple : categoriesDataStructure + .entrySet()) { + CategoryDefinition categoryDefinition = triple.getKey(); + List<SubCategoryDefinition> subList = new ArrayList<>(); + categoryDefinition.setSubcategories(subList); + Map<SubCategoryDefinition, List<GroupingDefinition>> value = triple.getValue(); + + for (Entry<SubCategoryDefinition, List<GroupingDefinition>> pair : value.entrySet()) { + SubCategoryDefinition subCategoryDefinition = pair.getKey(); + List<GroupingDefinition> list = pair.getValue(); + subList.add(subCategoryDefinition); + subCategoryDefinition.setGroupings(list); + } + categoryDataList.add(categoryDefinition); + } + product.setCategories(categoryDataList); + log.debug("Fetched categories for product {}, categories: {}", product.getUniqueId(), + Arrays.toString(categoryDataList.toArray())); + } + + private ProductMetadataData getProductMetadataDataFromProduct(Product product) { + ProductMetadataData productMetadata = new ProductMetadataData( + (ProductMetadataDataDefinition) product.getComponentMetadataDefinition().getMetadataDataDefinition()); + return productMetadata; + } + + @Override + public boolean isComponentExist(String id) { + return isComponentExist(id, NodeTypeEnum.Product); + } + + // @SuppressWarnings("unchecked") + // @Override + // public <T> Either<T, StorageOperationStatus> cloneComponent(T other, + // String version, boolean inTransaction) { + // return (Either<T, StorageOperationStatus>) cloneProduct((Product)other, + // version, inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> cloneComponent(T other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) cloneProduct((Product) other, version, targetLifecycle, + inTransaction); + } + + private Either<Product, StorageOperationStatus> cloneProduct(Product other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either<Product, StorageOperationStatus> result = null; + + try { + String origProductId = other.getUniqueId(); + other.setVersion(version); + other.setUniqueId(null); + + Either<Integer, StorageOperationStatus> counterStatus = getComponentInstanceCoutner(origProductId, + NodeTypeEnum.Product); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on product {}. status={}", origProductId, + counterStatus); + result = Either.right(status); + return result; + } + + Either<Product, StorageOperationStatus> createProductMD = createProduct(other, inTransaction); + if (createProductMD.isRight()) { + StorageOperationStatus status = createProductMD.right().value(); + log.debug("Failed to clone product. status= {}", status); + result = Either.right(status); + return result; + } + Product product = createProductMD.left().value(); + + Either<ImmutablePair<List<ComponentInstance>, Map<String, String>>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origProductId, product, + NodeTypeEnum.Product, NodeTypeEnum.Service, targetLifecycle, null); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either<Integer, StorageOperationStatus> setResourceInstanceCounter = setComponentInstanceCounter( + product.getUniqueId(), NodeTypeEnum.Product, counterStatus.left().value(), inTransaction); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on product {}. status={}", product.getUniqueId(), + setResourceInstanceCounter); + result = Either.right(status); + return result; + } + + result = this.getProduct(product.getUniqueId(), inTransaction); + if (result.isRight()) { + log.error("Cannot get full product from the graph. status is {}", result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Product retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private Either<Product, StorageOperationStatus> getByNamesAndVersion(String nameKey, String nameValue, + String version, Map<String, Object> additionalParams, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Product.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either<List<ProductMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Product, props, ProductMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List<ProductMetadataData> dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + if (dataList.size() > 1) { + log.debug("More that one instance of product for name {} and version {}", nameValue, version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + ProductMetadataData productData = dataList.get(0); + Either<Product, StorageOperationStatus> product = getProduct( + productData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (product.isRight()) { + log.debug("Failed to fetch product, name {} id {}", productData.getMetadataDataDefinition().getName(), + productData.getMetadataDataDefinition().getUniqueId()); + } + return product; + } + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + @Override + public Product getDefaultComponent() { + return new Product(); + } + + @Override + protected <T extends org.openecomp.sdc.be.model.Component> StorageOperationStatus updateDerived( + org.openecomp.sdc.be.model.Component component, org.openecomp.sdc.be.model.Component currentComponent, + ComponentMetadataData componentData, Class<T> clazz) { + log.debug("Derived class isn't supported for product"); + return StorageOperationStatus.OK; + } + + @Override + public Either<Integer, StorageOperationStatus> increaseAndGetComponentInstanceCounter(String componentId, + boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Product, inTransaction); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, + ComponentMetadataData componentData, NodeTypeEnum type) { + // As agreed with Ella, update categories - delete old and create new + StorageOperationStatus status = StorageOperationStatus.OK; + List<CategoryDefinition> newcategories = component.getCategories(); + List<CategoryDefinition> currentcategories = currentComponent.getCategories(); + if (newcategories != null) { + if (currentcategories != null && !currentcategories.isEmpty()) { + Either<List<GroupingData>, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, currentComponent); + if (findGroupingsForComponent.isRight()) { + status = findGroupingsForComponent.right().value(); + } + List<GroupingData> groupingDataToDissociate = findGroupingsForComponent.left().value(); + TitanOperationStatus titanStatus = dissociateCategoriesFromProduct((ProductMetadataData) componentData, + groupingDataToDissociate); + if (titanStatus != TitanOperationStatus.OK) { + status = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } + if (!newcategories.isEmpty()) { + Either<List<GroupingData>, StorageOperationStatus> findGroupingsForComponent = findGroupingsForComponent( + NodeTypeEnum.ProductGrouping, component); + if (findGroupingsForComponent.isRight()) { + status = findGroupingsForComponent.right().value(); + } + List<GroupingData> groupingDataToAssociate = findGroupingsForComponent.left().value(); + TitanOperationStatus titanStatus = associateCategoriesToProduct((ProductMetadataData) componentData, + groupingDataToAssociate); + if (titanStatus != TitanOperationStatus.OK) { + status = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } + } + return status; + } + + @SuppressWarnings("unchecked") + public Either<List<Product>, StorageOperationStatus> getFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction) { + return (Either<List<Product>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getFollowedComponent( + userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Product); + } + + @Override + public Either<Component, StorageOperationStatus> getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Product, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertProductDataToProduct((ProductMetadataData) componentMetadataData); + } + + @Override + public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String productName) { + return validateComponentNameUniqueness(productName, titanGenericDao, NodeTypeEnum.Product); + } + + @SuppressWarnings("unchecked") + @Override + public Either<Component, StorageOperationStatus> markComponentToDelete(Component componentToDelete, + boolean inTransaction) { + // markComponentToDelete is not defined yet for products + return (Either<Component, StorageOperationStatus>) (Either<?, StorageOperationStatus>) deleteProduct( + componentToDelete.getUniqueId(), inTransaction); + } + + @Override + public void rollback() { + titanGenericDao.rollback(); + + } + + @Override + public void commit() { + titanGenericDao.commit(); + } + + @Override + public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) { + return isComponentInUse(componentId, NodeTypeEnum.Product); + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + // markForDeletion for products is not implemented yet + return Either.left(new ArrayList<>()); + } + + public Either<Product, StorageOperationStatus> getProductByNameAndVersion(String productName, String productVersion, + boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), + ValidationUtils.normaliseComponentName(productName), productVersion, null, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, + ComponentParametersView componentParametersView, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getProduct(id, false); + } + + public Either<Product, StorageOperationStatus> updateProduct(Product product, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either<Product, StorageOperationStatus>) updateComponentFilterResult(product, inTransaction, + titanGenericDao, product.getClass(), NodeTypeEnum.Service, filterResultView); + } + + @Override + protected <T> Either<T, StorageOperationStatus> updateComponentFilterResult(T component, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either<T, StorageOperationStatus>) updateProduct((Product) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java new file mode 100644 index 0000000000..7d775b3b3d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java @@ -0,0 +1,2788 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.StringJoiner; +import java.util.function.Consumer; +import java.util.function.Supplier; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.codehaus.jackson.JsonNode; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.ObjectCodec; +import org.codehaus.jackson.map.DeserializationContext; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.graph.GraphElementFactory; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphElementTypeEnum; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.PropertyRule; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintType; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterOrEqualConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.GreaterThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.InRangeConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessOrEqualConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.LessThanConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.MinLengthConstraint; +import org.openecomp.sdc.be.model.tosca.constraints.ValidValuesConstraint; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.DataTypeData; +import org.openecomp.sdc.be.resources.data.InputValueData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.common.api.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; + +@Component("property-operation") +public class PropertyOperation extends AbstractOperation implements IPropertyOperation { + + public static void main(String[] args) { + + List<Pattern> buildFunctionPatterns = buildFunctionPatterns(); + + for (Pattern pattern : buildFunctionPatterns) { + + String[] strs = { "str_replace", "{ str_replace:", " {str_replace:", " { str_replace:", "{str_replace:" }; + for (String str : strs) { + Matcher m = pattern.matcher(str); + System.out.println(pattern.pattern() + " " + str + " " + m.find()); + } + } + + } + + public static final String PROPERTY = "property"; + + public PropertyOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(PropertyOperation.class.getName()); + + private static List<Pattern> functionPatterns = null; + + static { + + functionPatterns = buildFunctionPatterns(); + } + + /** + * The value of functions is in a json format. Build pattern for each function name + * + * { str_replace: .... } {str_replace: .... } {str_replace: .... } { str_replace: .... } + * + * @return + */ + private static List<Pattern> buildFunctionPatterns() { + + List<Pattern> functionPatterns = new ArrayList<>(); + + String[] functions = { "get_input", "get_property" }; + + for (String function : functions) { + Pattern pattern = Pattern.compile("^[ ]*\\{[ ]*" + function + ":"); + functionPatterns.add(pattern); + } + + return functionPatterns; + } + + @Override + public Either<PropertyDefinition, StorageOperationStatus> getPropertyOfResource(String propertyName, String resourceId) { + + String propertyId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName); + + Either<PropertyData, TitanOperationStatus> getResult = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + if (getResult.isLeft()) { + PropertyData propertyData = getResult.left().value(); + return Either.left(convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId)); + } else { + TitanOperationStatus titanStatus = getResult.right().value(); + log.debug("Node with id {} was not found in the graph. Status: {}", propertyId, titanStatus); + StorageOperationStatus storageOperationStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + return Either.right(storageOperationStatus); + } + + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.model.operations.api.IPropertyOperation# addPropertyToResource(java.lang.String, org.openecomp.sdc.be.model.PropertyDefinition, org.openecomp.sdc.be.dao.neo4j.datatype.NodeTypeEnum, java.lang.String) + */ + /* + * @Override public Either<PropertyDefinition, StorageOperationStatus> addPropertyToResource( String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String resourceId) { + * + * StorageOperationStatus isValidProperty = isTypeExistsAndValid(propertyDefinition); if (isValidProperty != StorageOperationStatus.OK) { return Either.right(isValidProperty); } + * + * Either<PropertyData, TitanOperationStatus> status = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + * + * if (status.isRight()) { titanGenericDao.rollback(); log.error("Failed to add property " + propertyName + " to resource " + resourceId); return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status. right().value())); } else + * { titanGenericDao.commit(); PropertyData propertyData = status.left().value(); + * + * PropertyDefinition propertyDefResult = convertPropertyDataToPropertyDefinition(propertyData, propertyName, resourceId); log.debug("The returned PropertyDefintion is {}", propertyDefinition); return Either.left(propertyDefResult); } + * + * + * } + */ + private StorageOperationStatus isTypeExistsAndValid(PropertyDefinition propertyDefinition) { + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyDefinition.getType()); + + if (type == null) { + return StorageOperationStatus.INVALID_TYPE; + } + + String propertyType = propertyDefinition.getType(); + String innerType = null; + String value = propertyDefinition.getDefaultValue(); + + if (propertyType.equals(ToscaPropertyType.LIST) || propertyType.equals(ToscaPropertyType.MAP)) { + SchemaDefinition schema; + if ((schema = propertyDefinition.getSchema()) != null) { + PropertyDataDefinition property; + if ((property = schema.getProperty()) != null) { + innerType = property.getType(); + + } + } + } + + PropertyTypeValidator validator = type.getValidator(); + + if (value == null || (EMPTY_VALUE != null && EMPTY_VALUE.equals(propertyDefinition.getDefaultValue()))) { + return StorageOperationStatus.OK; + } else { + boolean isValid = validator.isValid(value, innerType, null); + if (true == isValid) { + return StorageOperationStatus.OK; + } else { + return StorageOperationStatus.INVALID_VALUE; + } + } + + } + + public PropertyDefinition convertPropertyDataToPropertyDefinition(PropertyData propertyDataResult, String propertyName, String resourceId) { + log.debug("The object returned after create property is {}", propertyDataResult); + + PropertyDefinition propertyDefResult = new PropertyDefinition(propertyDataResult.getPropertyDataDefinition()); + propertyDefResult.setConstraints(convertConstraints(propertyDataResult.getConstraints())); + propertyDefResult.setName(propertyName); + propertyDefResult.setParentUniqueId(resourceId); + + return propertyDefResult; + } + + public static class PropertyConstraintSerialiser implements JsonSerializer<PropertyConstraint> { + + @Override + public JsonElement serialize(PropertyConstraint src, Type typeOfSrc, JsonSerializationContext context) { + JsonParser parser = new JsonParser(); + JsonObject result = new JsonObject(); + JsonArray jsonArray = new JsonArray(); + if (src instanceof InRangeConstraint) { + InRangeConstraint rangeConstraint = (InRangeConstraint) src; + jsonArray.add(parser.parse(rangeConstraint.getRangeMinValue())); + jsonArray.add(parser.parse(rangeConstraint.getRangeMaxValue())); + result.add("inRange", jsonArray); + } else if (src instanceof GreaterThanConstraint) { + GreaterThanConstraint greaterThanConstraint = (GreaterThanConstraint) src; + jsonArray.add(parser.parse(greaterThanConstraint.getGreaterThan())); + result.add("greaterThan", jsonArray); + } else if (src instanceof LessOrEqualConstraint) { + LessOrEqualConstraint lessOrEqualConstraint = (LessOrEqualConstraint) src; + jsonArray.add(parser.parse(lessOrEqualConstraint.getLessOrEqual())); + result.add("lessOrEqual", jsonArray); + } else { + log.warn("PropertyConstraint {} is not supported. Ignored.", src.getClass().getName()); + } + + return result; + } + + } + + public static class PropertyConstraintDeserialiser implements JsonDeserializer<PropertyConstraint> { + + @Override + public PropertyConstraint deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + + PropertyConstraint propertyConstraint = null; + + Set<Entry<String, JsonElement>> set = json.getAsJsonObject().entrySet(); + + if (set.size() == 1) { + Entry<String, JsonElement> element = set.iterator().next(); + String key = element.getKey(); + JsonElement value = element.getValue(); + + ConstraintType constraintType = ConstraintType.getByType(key); + if (constraintType == null) { + log.warn("ConstraintType was not found for constraint name:{}", key); + } else { + switch (constraintType) { + case IN_RANGE: + + if (value != null) { + if (value instanceof JsonArray) { + JsonArray rangeArray = (JsonArray) value; + if (rangeArray.size() != 2) { + log.error("The range constraint content is invalid. value = {}", value); + } else { + InRangeConstraint rangeConstraint = new InRangeConstraint(); + String minValue = rangeArray.get(0).getAsString(); + String maxValue = rangeArray.get(1).getAsString(); + rangeConstraint.setRangeMinValue(minValue); + rangeConstraint.setRangeMaxValue(maxValue); + propertyConstraint = rangeConstraint; + } + } + + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + case GREATER_THAN: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString); + propertyConstraint = new GreaterThanConstraint(asString); + break; + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + + case LESS_THAN: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to LessThanConstraint object. value = {}", asString); + propertyConstraint = new LessThanConstraint(asString); + break; + } else { + log.warn("The value of LessThanConstraint is null"); + } + break; + case GREATER_OR_EQUAL: + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to GreaterThanConstraint object. value = {}", asString); + propertyConstraint = new GreaterOrEqualConstraint(asString); + break; + } else { + log.warn("The value of GreaterOrEqualConstraint is null"); + } + break; + case LESS_OR_EQUAL: + + if (value != null) { + String asString = value.getAsString(); + log.debug("Before adding value to LessOrEqualConstraint object. value = {}", asString); + propertyConstraint = new LessOrEqualConstraint(asString); + } else { + log.warn("The value of GreaterThanConstraint is null"); + } + break; + + case VALID_VALUES: + + if (value != null) { + if (value instanceof JsonArray) { + JsonArray rangeArray = (JsonArray) value; + if (rangeArray.size() == 0) { + log.error("The valid values constraint content is invalid. value = {}", value); + } else { + ValidValuesConstraint vvConstraint = new ValidValuesConstraint(); + List<String> validValues = new ArrayList<String>(); + for (JsonElement jsonElement : rangeArray) { + String item = jsonElement.getAsString(); + validValues.add(item); + } + vvConstraint.setValidValues(validValues); + propertyConstraint = vvConstraint; + } + } + + } else { + log.warn("The value of ValidValuesConstraint is null"); + } + break; + + case MIN_LENGTH: + if (value != null) { + int asInt = value.getAsInt(); + log.debug("Before adding value to Min Length object. value = {}", asInt); + propertyConstraint = new MinLengthConstraint(asInt); + break; + } else { + log.warn("The value of MinLengthConstraint is null"); + } + break; + default: + log.warn("Key {} is not supported. Ignored.", key); + } + } + } + + return propertyConstraint; + } + + } + + public TitanOperationStatus addPropertiesToGraph(Map<String, PropertyDefinition> properties, String resourceId, Map<String, DataTypeDefinition> dataTypes) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + if (properties != null) { + for (Entry<String, PropertyDefinition> entry : properties.entrySet()) { + + String propertyName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.ILLEGAL_ARGUMENT; + } + + Either<PropertyData, TitanOperationStatus> addPropertyToGraph = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + + if (addPropertyToGraph.isRight()) { + return addPropertyToGraph.right().value(); + } + } + } + + return TitanOperationStatus.OK; + + } + + public TitanOperationStatus addPropertiesToGraph(TitanVertex metadataVertex, Map<String, PropertyDefinition> properties, Map<String, DataTypeDefinition> dataTypes, String resourceId) { + + if (properties != null) { + for (Entry<String, PropertyDefinition> entry : properties.entrySet()) { + + String propertyName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(propertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.error("Property {} is invalid. Status is {}", propertyDefinition, validateAndUpdateProperty); + return TitanOperationStatus.ILLEGAL_ARGUMENT; + } + + TitanOperationStatus addPropertyToGraph = addPropertyToGraphByVertex(metadataVertex, propertyName, propertyDefinition, resourceId); + + if (!addPropertyToGraph.equals(TitanOperationStatus.OK)) { + return addPropertyToGraph; + } + } + } + + return TitanOperationStatus.OK; + + } + + public Either<PropertyData, StorageOperationStatus> addProperty(String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + Either<PropertyData, TitanOperationStatus> either = addPropertyToGraph(propertyName, propertyDefinition, resourceId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + /** + * @param propertyDefinition + * @return + */ + @Override + public StorageOperationStatus validateAndUpdateProperty(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) { + + log.trace("Going to validate property type and value. {}", propertyDefinition); + + String propertyType = propertyDefinition.getType(); + String value = propertyDefinition.getDefaultValue(); + + ToscaPropertyType type = getType(propertyType); + + if (type == null) { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + if (dataTypeDefinition == null) { + log.debug("The type {} of property cannot be found.", propertyType); + return StorageOperationStatus.INVALID_TYPE; + } + + StorageOperationStatus status = validateAndUpdateComplexValue(propertyDefinition, propertyType, value, dataTypeDefinition, dataTypes); + + return status; + + } + String innerType = null; + + Either<String, TitanOperationStatus> checkInnerType = getInnerType(type, () -> propertyDefinition.getSchema()); + if (checkInnerType.isRight()) { + return StorageOperationStatus.INVALID_TYPE; + } + innerType = checkInnerType.left().value(); + + log.trace("After validating property type {}", propertyType); + + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.info("The value {} of property from type {} is invalid", value, type); + return StorageOperationStatus.INVALID_VALUE; + } + + PropertyValueConverter converter = type.getConverter(); + + if (isEmptyValue(value)) { + log.debug("Default value was not sent for property {}. Set default value to {}", propertyDefinition.getName(), EMPTY_VALUE); + propertyDefinition.setDefaultValue(EMPTY_VALUE); + } else if (false == isEmptyValue(value)) { + String convertedValue = converter.convert(value, innerType, dataTypes); + propertyDefinition.setDefaultValue(convertedValue); + } + return StorageOperationStatus.OK; + } + + /* + * public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType) { + * + * log. trace("Going to validate property value and its type. type = {}, value = {}" ,propertyType, value); + * + * ToscaPropertyType type = getType(propertyType); + * + * if (type == null) { + * + * Either<DataTypeDefinition, TitanOperationStatus> externalDataType = getExternalDataType(propertyType); if (externalDataType.isRight()) { TitanOperationStatus status = externalDataType.right().value(); log.debug("The type " + propertyType + + * " of property cannot be found. Status is " + status); if (status != TitanOperationStatus.NOT_FOUND) { BeEcompErrorManager.getInstance(). logBeInvalidTypeError("validate property type", propertyType, "property"); } return Either.right(false); } + * + * DataTypeDefinition dataTypeDefinition = externalDataType.left().value(); + * + * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); return Either.right(false); } + * + * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value(); + * + * ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, allDataTypes); + * + * if (validateResult.right.booleanValue() == false) { log.debug("The value {} of property from type {} is invalid", value, propertyType); return Either.right(false); } + * + * JsonElement jsonElement = validateResult.left; + * + * String valueFromJsonElement = getValueFromJsonElement(jsonElement); + * + * return Either.left(valueFromJsonElement); + * + * } + * + * log.trace("After validating property type " + propertyType); + * + * boolean isValidProperty = isValidValue(type, value, innerType); if (false == isValidProperty) { log.debug("The value {} of property from type {} is invalid", value, type); return Either.right(false); } + * + * + * Object convertedValue = value; if (false == isEmptyValue(value)) { PropertyValueConverter converter = type.getConverter(); convertedValue = converter.convert(value, null); } + * + * return Either.left(convertedValue); } + */ + + public Either<PropertyData, TitanOperationStatus> addPropertyToGraph(String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + List<PropertyConstraint> constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", propertyData); + Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, propertyData, GraphEdgeLabels.PROPERTY, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", resourceId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addPropertyToGraphByVertex(TitanVertex metadataVertex, String propertyName, PropertyDefinition propertyDefinition, String resourceId) { + + List<PropertyConstraint> constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(resourceId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + log.debug("Before adding property to graph {}", propertyData); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData); + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. status is {}", propertyName, operationStatus); + return operationStatus; + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + TitanVertex propertyVertex = createNodeResult.left().value(); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(metadataVertex, propertyVertex, GraphEdgeLabels.PROPERTY, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", resourceId, propertyName, createRelResult); + return createRelResult; + } + + return createRelResult; + + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + // public Either<PropertyData, StorageOperationStatus> + // deletePropertyFromGraphFromBl(String propertyId) { + // + // } + + public Either<PropertyData, StorageOperationStatus> deleteProperty(String propertyId) { + Either<PropertyData, TitanOperationStatus> either = deletePropertyFromGraph(propertyId); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + public Either<PropertyData, TitanOperationStatus> deletePropertyFromGraph(String propertyId) { + log.debug("Before deleting property from graph {}", propertyId); + return titanGenericDao.deleteNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + } + + public Either<PropertyData, StorageOperationStatus> updateProperty(String propertyId, PropertyDefinition newPropertyDefinition, Map<String, DataTypeDefinition> dataTypes) { + + StorageOperationStatus validateAndUpdateProperty = validateAndUpdateProperty(newPropertyDefinition, dataTypes); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + return Either.right(validateAndUpdateProperty); + } + + Either<PropertyData, TitanOperationStatus> either = updatePropertyFromGraph(propertyId, newPropertyDefinition); + if (either.isRight()) { + StorageOperationStatus storageStatus = DaoStatusConverter.convertTitanStatusToStorageStatus(either.right().value()); + return Either.right(storageStatus); + } + return Either.left(either.left().value()); + } + + public Either<PropertyData, TitanOperationStatus> updatePropertyFromGraph(String propertyId, PropertyDefinition propertyDefinition) { + if (log.isDebugEnabled()) + log.debug("Before updating property on graph {}", propertyId); + + // get the original property data + Either<PropertyData, TitanOperationStatus> statusProperty = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + if (statusProperty.isRight()) { + log.debug("Problem while get property with id {}. Reason - {}", propertyId, statusProperty.right().value().name()); + return Either.right(statusProperty.right().value()); + } + PropertyData orgPropertyData = statusProperty.left().value(); + PropertyDataDefinition orgPropertyDataDefinition = orgPropertyData.getPropertyDataDefinition(); + + // create new property data to update + PropertyData newPropertyData = new PropertyData(); + newPropertyData.setPropertyDataDefinition(propertyDefinition); + PropertyDataDefinition newPropertyDataDefinition = newPropertyData.getPropertyDataDefinition(); + + // update the original property data with new values + if (orgPropertyDataDefinition.getDefaultValue() == null) { + orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue()); + } else { + if (!orgPropertyDataDefinition.getDefaultValue().equals(newPropertyDataDefinition.getDefaultValue())) { + orgPropertyDataDefinition.setDefaultValue(newPropertyDataDefinition.getDefaultValue()); + } + } + if (orgPropertyDataDefinition.getDescription() == null) { + orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription()); + } else { + if (!orgPropertyDataDefinition.getDescription().equals(newPropertyDataDefinition.getDescription())) { + orgPropertyDataDefinition.setDescription(newPropertyDataDefinition.getDescription()); + } + } + if (!orgPropertyDataDefinition.getType().equals(newPropertyDataDefinition.getType())) { + orgPropertyDataDefinition.setType(newPropertyDataDefinition.getType()); + } + if (newPropertyData.getConstraints() != null) { + orgPropertyData.setConstraints(newPropertyData.getConstraints()); + } + orgPropertyDataDefinition.setSchema(newPropertyDataDefinition.getSchema()); + + return titanGenericDao.updateNode(orgPropertyData, PropertyData.class); + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + public Either<PropertyData, TitanOperationStatus> addPropertyToNodeType(String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) { + + List<PropertyConstraint> constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + if (log.isDebugEnabled()) + log.debug("Before adding property to graph {}", propertyData); + Either<PropertyData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData, PropertyData.class); + if (log.isDebugEnabled()) + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. Status is {}", propertyName, operationStatus); + return Either.right(operationStatus); + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + + UniqueIdData uniqueIdData = new UniqueIdData(nodeType, uniqueId); + log.debug("Before associating {} to property {}.", uniqueIdData, propertyName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(uniqueIdData, propertyData, GraphEdgeLabels.PROPERTY, props); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to associate resource {} to property {} in graph. Status is {}", uniqueId, propertyName, operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + public TitanOperationStatus addPropertyToNodeType(TitanVertex elementVertex, String propertyName, PropertyDefinition propertyDefinition, NodeTypeEnum nodeType, String uniqueId) { + + List<PropertyConstraint> constraints = propertyDefinition.getConstraints(); + + propertyDefinition.setUniqueId(UniqueIdBuilder.buildPropertyUniqueId(uniqueId, propertyName)); + PropertyData propertyData = new PropertyData(propertyDefinition, convertConstraintsToString(constraints)); + + if (log.isDebugEnabled()) + log.debug("Before adding property to graph {}", propertyData); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(propertyData); + if (log.isDebugEnabled()) + log.debug("After adding property to graph {}", propertyData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add property {} to graph. status is {} ", propertyName, operationStatus); + return operationStatus; + } + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), propertyName); + + TitanOperationStatus createRelResult = titanGenericDao.createEdge(elementVertex, propertyData, GraphEdgeLabels.PROPERTY, props); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to property {} in graph. status is {}", uniqueId, propertyName, createRelResult); + return createRelResult; + } + + return createRelResult; + + } + + public Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId) { + + Map<String, PropertyDefinition> resourceProps = new HashMap<String, PropertyDefinition>(); + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, + PropertyData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus operationStatus = childrenNodes.right().value(); + return Either.right(operationStatus); + } + + List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + PropertyData propertyData = immutablePair.getKey(); + PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId); + resourceProps.put(propertyName, propertyDefinition); + } + + } + + log.debug("The properties associated to node {} are {}", uniqueId, resourceProps); + return Either.left(resourceProps); + } + + public Either<Map<String, PropertyDefinition>, StorageOperationStatus> deleteAllPropertiesAssociatedToNode(NodeTypeEnum nodeType, String uniqueId) { + + Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesOfNodeRes = findPropertiesOfNode(nodeType, uniqueId); + + if (propertiesOfNodeRes.isRight()) { + TitanOperationStatus status = propertiesOfNodeRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.right(StorageOperationStatus.OK); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + Map<String, PropertyDefinition> value = propertiesOfNodeRes.left().value(); + for (PropertyDefinition propertyDefinition : value.values()) { + + String propertyUid = propertyDefinition.getUniqueId(); + Either<PropertyData, TitanOperationStatus> deletePropertyRes = deletePropertyFromGraph(propertyUid); + if (deletePropertyRes.isRight()) { + log.error("Failed to delete property with id " + propertyUid); + TitanOperationStatus status = deletePropertyRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + log.debug("The properties deleted from node {} are {}", uniqueId, value); + return Either.left(value); + } + + /** + * fetch all properties under a given resource(includes its parents' resources) + * + * @param resourceId + * @param properties + * @return + */ + public TitanOperationStatus findAllResourcePropertiesRecursively(String resourceId, List<PropertyDefinition> properties) { + final NodeElementFetcher<PropertyDefinition> singleNodeFetcher = (resourceIdParam, attributesParam) -> findPropertiesOfNode(NodeTypeEnum.Resource, resourceIdParam, attributesParam); + return findAllResourceElementsDefinitionRecursively(resourceId, properties, singleNodeFetcher); + } + + /** + * + * + * @param nodeType + * @param uniqueId + * @param properties + * @return + */ + protected TitanOperationStatus findPropertiesOfNode(NodeTypeEnum nodeType, String uniqueId, List<PropertyDefinition> properties) { + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), uniqueId, GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, + PropertyData.class); + + if (childrenNodes.isRight()) { + TitanOperationStatus status = childrenNodes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + } + return status; + } + + List<ImmutablePair<PropertyData, GraphEdge>> values = childrenNodes.left().value(); + if (values != null) { + + for (ImmutablePair<PropertyData, GraphEdge> immutablePair : values) { + GraphEdge edge = immutablePair.getValue(); + String propertyName = (String) edge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (log.isDebugEnabled()) + log.debug("Property {} is associated to node {}", propertyName, uniqueId); + PropertyData propertyData = immutablePair.getKey(); + PropertyDefinition propertyDefinition = this.convertPropertyDataToPropertyDefinition(propertyData, propertyName, uniqueId); + + properties.add(propertyDefinition); + + if (log.isTraceEnabled()) + log.trace("findPropertiesOfNode - property {} associated to node {}", propertyDefinition, uniqueId); + } + + } + + return TitanOperationStatus.OK; + } + + public boolean isPropertyExist(List<PropertyDefinition> properties, String resourceUid, String propertyName) { + + if (properties == null) { + return false; + } + + for (PropertyDefinition propertyDefinition : properties) { + String parentUniqueId = propertyDefinition.getParentUniqueId(); + String name = propertyDefinition.getName(); + + if (parentUniqueId.equals(resourceUid) && name.equals(propertyName)) { + return true; + } + } + + return false; + + } + + /** + * add property to resource instance + * + * @param innerType + * TODO // * @param resourceInstanceProperty // * @param resourceInstanceId // * @param index + * + * @return + */ + /* + * public Either<PropertyValueData, TitanOperationStatus> addPropertyToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index) { + * + * Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + * + * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + * + * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { + * + * PropertyData propertyData = findPropertyDefRes.left().value(); ComponentInstanceData resourceInstanceData = findResInstanceRes.left().value(); + * + * ImmutablePair<TitanOperationStatus, String> isPropertyValueExists = findPropertyValue(resourceInstanceId, propertyId); if (isPropertyValueExists.getLeft() == TitanOperationStatus.ALREADY_EXIST) { log.debug("The property " + propertyId + + * " already added to the resource instance " + resourceInstanceId); resourceInstanceProperty.setValueUniqueUid(isPropertyValueExists.getRight ()); Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance = + * updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); if (updatePropertyOfResourceInstance.isRight()) { BeEcompErrorManager.getInstance().logInternalFlowError( "UpdatePropertyValueOnComponentInstance", + * "Failed to update property value on instance. Status is " + updatePropertyOfResourceInstance.right().value(), ErrorSeverity.ERROR); return Either.right(updatePropertyOfResourceInstance.right().value()); } return + * Either.left(updatePropertyOfResourceInstance.left().value()); } + * + * if (isPropertyValueExists.getLeft() != TitanOperationStatus.NOT_FOUND) { log.debug("After finding property value of {} on component instance {}", propertyId, resourceInstanceId); return Either.right(isPropertyValueExists.getLeft()); } + * + * String propertyType = propertyData.getPropertyDataDefinition().getType(); String value = resourceInstanceProperty.getValue(); Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) { + * newValue = object.toString(); } } + * + * String uniqueId = UniqueIdBuilder.buildResourceInstancePropertyValueUid( resourceInstanceData.getUniqueId(), index); PropertyValueData propertyValueData = new PropertyValueData(); propertyValueData.setUniqueId(uniqueId); + * propertyValueData.setValue(newValue); + * + * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance(). + * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } addRulesToNewPropertyValue(propertyValueData, + * resourceInstanceProperty, resourceInstanceId); + * + * log.debug("Before adding property value to graph {}", propertyValueData); Either<PropertyValueData, TitanOperationStatus> createNodeResult = titanGenericDao .createNode(propertyValueData, PropertyValueData.class); + * log.debug("After adding property value to graph {}", propertyValueData); + * + * Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao .createRelation(propertyValueData, propertyData, GraphEdgeLabels.PROPERTY_IMPL, null); + * + * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate property value " + uniqueId + " to property " + propertyId + + * " in graph. status is " + operationStatus); return Either.right(operationStatus); } + * + * createRelResult = titanGenericDao .createRelation(resourceInstanceData, propertyValueData, GraphEdgeLabels.PROPERTY_VALUE, null); + * + * if (createRelResult.isRight()) { TitanOperationStatus operationStatus = createNodeResult.right() .value(); //TODO: change logger log.error("Failed to associate resource instance " + resourceInstanceId + " property value " + uniqueId + + * " in graph. status is " + operationStatus); return Either.right(operationStatus); } + * + * return Either.left(createNodeResult.left().value()); } else { log.error("property value already exists."); return Either.right(TitanOperationStatus.ALREADY_EXIST); } + * + * } + */ + public ImmutablePair<String, Boolean> validateAndUpdateRules(String propertyType, List<PropertyRule> rules, String innerType, Map<String, DataTypeDefinition> dataTypes, boolean isValidate) { + + if (rules == null || rules.isEmpty() == true) { + return new ImmutablePair<String, Boolean>(null, true); + } + + for (PropertyRule rule : rules) { + String value = rule.getValue(); + Either<Object, Boolean> updateResult = validateAndUpdatePropertyValue(propertyType, value, isValidate, innerType, dataTypes); + if (updateResult.isRight()) { + Boolean status = updateResult.right().value(); + if (status == false) { + return new ImmutablePair<String, Boolean>(value, status); + } + } else { + String newValue = null; + Object object = updateResult.left().value(); + if (object != null) { + newValue = object.toString(); + } + rule.setValue(newValue); + } + } + + return new ImmutablePair<String, Boolean>(null, true); + } + + public void addRulesToNewPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + + List<PropertyRule> rules = resourceInstanceProperty.getRules(); + if (rules == null) { + PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId); + rules = new ArrayList<>(); + rules.add(propertyRule); + } else { + rules = sortRules(rules); + } + + propertyValueData.setRules(rules); + } + + private PropertyRule buildRuleFromPath(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + List<String> path = resourceInstanceProperty.getPath(); + // FOR BC. Since old Property values on VFC/VF does not have rules on + // graph. + // Update could be done on one level only, thus we can use this + // operation to avoid migration. + if (path == null || path.isEmpty() == true) { + path = new ArrayList<>(); + path.add(resourceInstanceId); + } + PropertyRule propertyRule = new PropertyRule(); + propertyRule.setRule(path); + propertyRule.setValue(propertyValueData.getValue()); + return propertyRule; + } + + private List<PropertyRule> sortRules(List<PropertyRule> rules) { + + // TODO: sort the rules by size and binary representation. + // (x, y, .+) --> 110 6 priority 1 + // (x, .+, z) --> 101 5 priority 2 + + return rules; + } + + public ImmutablePair<TitanOperationStatus, String> findPropertyValue(String resourceInstanceId, String propertyId) { + + log.debug("Going to check whether the property {} already added to resource instance {}", propertyId, resourceInstanceId); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllRes = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceId); + if (getAllRes.isRight()) { + TitanOperationStatus status = getAllRes.right().value(); + log.trace("After fetching all properties of resource instance {}. Status is {}", resourceInstanceId, status); + return new ImmutablePair<TitanOperationStatus, String>(status, null); + } + + List<ComponentInstanceProperty> list = getAllRes.left().value(); + if (list != null) { + for (ComponentInstanceProperty instanceProperty : list) { + String propertyUniqueId = instanceProperty.getUniqueId(); + String valueUniqueUid = instanceProperty.getValueUniqueUid(); + log.trace("Go over property {} under resource instance {}. valueUniqueId = {}", propertyUniqueId, resourceInstanceId, valueUniqueUid); + if (propertyId.equals(propertyUniqueId) && valueUniqueUid != null) { + log.debug("The property {} already created under resource instance {}", propertyId, resourceInstanceId); + return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.ALREADY_EXIST, valueUniqueUid); + } + } + } + + return new ImmutablePair<TitanOperationStatus, String>(TitanOperationStatus.NOT_FOUND, null); + } + + /** + * update value of property on resource instance + * + * @param resourceInstanceProperty + * @param resourceInstanceId + * @return + */ + /* + * public Either<PropertyValueData, TitanOperationStatus> updatePropertyOfResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + * + * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao .getNode(UniqueIdBuilder + * .getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + * + * if (findResInstanceRes.isRight()) { TitanOperationStatus status = findResInstanceRes.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String propertyId = resourceInstanceProperty.getUniqueId(); Either<PropertyData, TitanOperationStatus> findPropertyDefRes = titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.Property), propertyId, PropertyData.class); + * + * if (findPropertyDefRes.isRight()) { TitanOperationStatus status = findPropertyDefRes.right().value(); return Either.right(status); } + * + * String valueUniqueUid = resourceInstanceProperty.getValueUniqueUid(); if (valueUniqueUid == null) { return Either.right(TitanOperationStatus.INVALID_ID); } else { Either<PropertyValueData, TitanOperationStatus> findPropertyValueRes = + * titanGenericDao .getNode(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, PropertyValueData.class); if (findPropertyValueRes.isRight()) { TitanOperationStatus status = findPropertyValueRes.right().value(); if + * (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * String value = resourceInstanceProperty.getValue(); + * + * Either<ImmutablePair<PropertyData, GraphEdge>, TitanOperationStatus> child = titanGenericDao.getChild(UniqueIdBuilder .getKeyByNodeType(NodeTypeEnum.PropertyValue), valueUniqueUid, GraphEdgeLabels.PROPERTY_IMPL, NodeTypeEnum.Property, + * PropertyData.class); + * + * if (child.isRight()) { TitanOperationStatus status = child.right().value(); if (status == TitanOperationStatus.NOT_FOUND) { status = TitanOperationStatus.INVALID_ID; } return Either.right(status); } + * + * PropertyData propertyData = child.left().value().left; String propertyType = propertyData.getPropertyDataDefinition().getType(); + * + * log.debug("The type of the property {} is {}", propertyData.getUniqueId(), propertyType); + * + * Either<Object, Boolean> isValid = validateAndUpdatePropertyValue(propertyType, value); + * + * String newValue = value; if (isValid.isRight()) { Boolean res = isValid.right().value(); if (res == false) { return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } } else { Object object = isValid.left().value(); if (object != null) { + * newValue = object.toString(); } } PropertyValueData propertyValueData = findPropertyValueRes.left().value(); log.debug("Going to update property value from {} to {}", propertyValueData.getValue(), newValue); + * propertyValueData.setValue(newValue); + * + * ImmutablePair<String, Boolean> pair = validateAndUpdateRules(propertyType, resourceInstanceProperty.getRules()); if (pair.getRight() != null && pair.getRight() == false) { BeEcompErrorManager.getInstance(). + * logBeInvalidValueError("Add property value", pair.getLeft(), resourceInstanceProperty.getName(), propertyType); return Either.right(TitanOperationStatus.ILLEGAL_ARGUMENT); } updateRulesInPropertyValue(propertyValueData, + * resourceInstanceProperty, resourceInstanceId); + * + * Either<PropertyValueData, TitanOperationStatus> updateRes = titanGenericDao.updateNode(propertyValueData, PropertyValueData.class); if (updateRes.isRight()) { TitanOperationStatus status = updateRes.right().value(); return + * Either.right(status); } else { return Either.left(updateRes.left().value()); } } + * + * } + */ + + public void updateRulesInPropertyValue(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId) { + + List<PropertyRule> currentRules = propertyValueData.getRules(); + + List<PropertyRule> rules = resourceInstanceProperty.getRules(); + // if rules are not supported. + if (rules == null) { + + PropertyRule propertyRule = buildRuleFromPath(propertyValueData, resourceInstanceProperty, resourceInstanceId); + rules = new ArrayList<>(); + rules.add(propertyRule); + + if (currentRules != null) { + rules = mergeRules(currentRules, rules); + } + + } else { + // Full mode. all rules are sent in update operation. + rules = sortRules(rules); + } + + propertyValueData.setRules(rules); + + } + + private List<PropertyRule> mergeRules(List<PropertyRule> currentRules, List<PropertyRule> newRules) { + + List<PropertyRule> mergedRules = new ArrayList<>(); + + if (newRules == null || newRules.isEmpty() == true) { + return currentRules; + } + + for (PropertyRule rule : currentRules) { + PropertyRule propertyRule = new PropertyRule(rule.getRule(), rule.getValue()); + mergedRules.add(propertyRule); + } + + for (PropertyRule rule : newRules) { + PropertyRule foundRule = findRuleInList(rule, mergedRules); + if (foundRule != null) { + foundRule.setValue(rule.getValue()); + } else { + mergedRules.add(rule); + } + } + + return mergedRules; + } + + private PropertyRule findRuleInList(PropertyRule rule, List<PropertyRule> rules) { + + if (rules == null || rules.isEmpty() == true || rule.getRule() == null || rule.getRule().isEmpty() == true) { + return null; + } + + PropertyRule foundRule = null; + for (PropertyRule propertyRule : rules) { + if (rule.getRuleSize() != propertyRule.getRuleSize()) { + continue; + } + boolean equals = propertyRule.compareRule(rule); + if (equals == true) { + foundRule = propertyRule; + break; + } + } + + return foundRule; + } + + /** + * return all properties associated to resource instance. The result does contains the property unique id but not its type, default value... + * + * @param resourceInstanceUid + * @return + */ + public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid) { + + return getAllPropertiesOfResourceInstanceOnlyPropertyDefId(resourceInstanceUid, NodeTypeEnum.ResourceInstance); + + } + + /* + * public Either<ComponentInstanceProperty, StorageOperationStatus> addPropertyValueToResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, Integer index, boolean inTransaction) { + * + * /// #RULES SUPPORT /// Ignore rules received from client till support resourceInstanceProperty.setRules(null); /// /// + * + * Either<ComponentInstanceProperty, StorageOperationStatus> result = null; + * + * try { + * + * Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .addPropertyToResourceInstance(resourceInstanceProperty, resourceInstanceId, index); + * + * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result = + * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value(); + * + * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty); + * + * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } } + * + * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit(); + * } } } + * + * } + * + * public Either<ComponentInstanceProperty, StorageOperationStatus> updatePropertyValueInResourceInstance( ComponentInstanceProperty resourceInstanceProperty, String resourceInstanceId, boolean inTransaction) { + * + * Either<ComponentInstanceProperty, StorageOperationStatus> result = null; + * + * try { //TODO: verify validUniqueId exists Either<PropertyValueData, TitanOperationStatus> eitherStatus = this .updatePropertyOfResourceInstance(resourceInstanceProperty, resourceInstanceId); + * + * if (eitherStatus.isRight()) { log.error( "Failed to add property value {} to resource instance {} in Graph. status is {}" , resourceInstanceProperty, resourceInstanceId, eitherStatus.right().value().name()); result = + * Either.right(DaoStatusConverter .convertTitanStatusToStorageStatus(eitherStatus.right() .value())); return result; } else { PropertyValueData propertyValueData = eitherStatus.left() .value(); + * + * ComponentInstanceProperty propertyValueResult = buildResourceInstanceProperty( propertyValueData, resourceInstanceProperty); + * + * log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); result = Either.left(propertyValueResult); return result; } } + * + * finally { if (false == inTransaction) { if (result == null || result.isRight()) { log.error("Going to execute rollback on graph."); titanGenericDao.rollback(); } else { log.debug("Going to execute commit on graph."); titanGenericDao.commit(); + * } } } + * + * } + */ + + public Either<PropertyValueData, TitanOperationStatus> removePropertyOfResourceInstance(String propertyValueUid, String resourceInstanceId) { + + Either<ComponentInstanceData, TitanOperationStatus> findResInstanceRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), resourceInstanceId, ComponentInstanceData.class); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either<PropertyValueData, TitanOperationStatus> findPropertyDefRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.PropertyValue), propertyValueUid, PropertyValueData.class); + + if (findPropertyDefRes.isRight()) { + TitanOperationStatus status = findPropertyDefRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either<GraphRelation, TitanOperationStatus> relation = titanGenericDao.getRelation(findResInstanceRes.left().value(), findPropertyDefRes.left().value(), GraphEdgeLabels.PROPERTY_VALUE); + if (relation.isRight()) { + // TODO: add error in case of error + TitanOperationStatus status = relation.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + Either<PropertyValueData, TitanOperationStatus> deleteNode = titanGenericDao.deleteNode(findPropertyDefRes.left().value(), PropertyValueData.class); + if (deleteNode.isRight()) { + return Either.right(deleteNode.right().value()); + } + PropertyValueData value = deleteNode.left().value(); + return Either.left(value); + + } + + public Either<ComponentInstanceProperty, StorageOperationStatus> removePropertyValueFromResourceInstance(String propertyValueUid, String resourceInstanceId, boolean inTransaction) { + + Either<ComponentInstanceProperty, StorageOperationStatus> result = null; + + try { + + Either<PropertyValueData, TitanOperationStatus> eitherStatus = this.removePropertyOfResourceInstance(propertyValueUid, resourceInstanceId); + + if (eitherStatus.isRight()) { + log.error("Failed to remove property value {} from resource instance {} in Graph. status is {}", propertyValueUid, resourceInstanceId, eitherStatus.right().value().name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + PropertyValueData propertyValueData = eitherStatus.left().value(); + + ComponentInstanceProperty propertyValueResult = new ComponentInstanceProperty(); + propertyValueResult.setUniqueId(resourceInstanceId); + propertyValueResult.setValue(propertyValueData.getValue()); + + log.debug("The returned ResourceInstanceProperty is {}", propertyValueResult); + result = Either.left(propertyValueResult); + return result; + } + } + + finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public ComponentInstanceProperty buildResourceInstanceProperty(PropertyValueData propertyValueData, ComponentInstanceProperty resourceInstanceProperty) { + + String value = propertyValueData.getValue(); + String uid = propertyValueData.getUniqueId(); + ComponentInstanceProperty instanceProperty = new ComponentInstanceProperty(resourceInstanceProperty, value, uid); + instanceProperty.setPath(resourceInstanceProperty.getPath()); + + return instanceProperty; + } + + public static class PropertyConstraintJacksonDeserialiser extends org.codehaus.jackson.map.JsonDeserializer<PropertyConstraint> { + + @Override + public PropertyConstraint deserialize(org.codehaus.jackson.JsonParser json, DeserializationContext context) throws IOException, JsonProcessingException { + + ObjectCodec oc = json.getCodec(); + JsonNode node = oc.readTree(json); + return null; + } + } + + @Override + public boolean isPropertyDefaultValueValid(IComplexDefaultValue propertyDefinition, Map<String, DataTypeDefinition> dataTypes) { + if (propertyDefinition == null) { + return false; + } + boolean isValid = false; + String innerType = null; + String propertyType = propertyDefinition.getType(); + ToscaPropertyType type = getType(propertyType); + if (type == ToscaPropertyType.LIST || type == ToscaPropertyType.MAP) { + SchemaDefinition def = propertyDefinition.getSchema(); + if (def == null) { + return false; + } + PropertyDataDefinition propDef = def.getProperty(); + if (propDef == null) { + return false; + } + innerType = propDef.getType(); + } + String value = propertyDefinition.getDefaultValue(); + if (type != null) { + isValid = isValidValue(type, value, innerType, dataTypes); + } else { + log.trace("The given type {} is not a pre defined one.", propertyType); + + DataTypeDefinition foundDt = dataTypes.get(propertyType); + if (foundDt != null) { + isValid = isValidComplexValue(foundDt, value, dataTypes); + } else { + isValid = false; + } + } + return isValid; + } + + public boolean isPropertyTypeValid(IComplexDefaultValue property) { + + if (property == null) { + return false; + } + + if (ToscaPropertyType.isValidType(property.getType()) == null) { + + Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(property.getType()); + + if (definedInDataTypes.isRight()) { + return false; + } else { + Boolean isExist = definedInDataTypes.left().value(); + return isExist.booleanValue(); + } + + } + return true; + } + + @Override + public ImmutablePair<String, Boolean> isPropertyInnerTypeValid(IComplexDefaultValue property, Map<String, DataTypeDefinition> dataTypes) { + + if (property == null) { + return new ImmutablePair<String, Boolean>(null, false); + } + + SchemaDefinition schema; + PropertyDataDefinition innerProp; + String innerType = null; + if ((schema = property.getSchema()) != null) { + if ((innerProp = schema.getProperty()) != null) { + innerType = innerProp.getType(); + } + } + + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType == null) { + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("The inner type {} is not a data type", innerType); + return new ImmutablePair<String, Boolean>(innerType, false); + } else { + log.debug("The inner type {} is a data type. Data type definition is {}", innerType, dataTypeDefinition); + } + } + + return new ImmutablePair<String, Boolean>(innerType, true); + } + + private boolean isValidComplexValue(DataTypeDefinition foundDt, String value, Map<String, DataTypeDefinition> dataTypes) { + /* + * Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypesRes = getAllDataTypes(); if (allDataTypesRes.isRight()) { TitanOperationStatus status = allDataTypesRes.right().value(); + * log.debug("Failed to fetch data types from graph. Status is {}", status); return false; } + * + * Map<String, DataTypeDefinition> allDataTypes = allDataTypesRes.left().value(); + */ + ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter.validateAndUpdate(value, foundDt, dataTypes); + + log.trace("The result after validating complex value of type {} is {}", foundDt.getName(), validateAndUpdate); + + return validateAndUpdate.right.booleanValue(); + + } + + private Either<Map<String, DataTypeDefinition>, TitanOperationStatus> findAllDataTypeDefinition(DataTypeDefinition dataTypeDefinition) { + + Map<String, DataTypeDefinition> nameToDataTypeDef = new HashMap<>(); + + DataTypeDefinition typeDefinition = dataTypeDefinition; + + while (typeDefinition != null) { + + List<PropertyDefinition> properties = typeDefinition.getProperties(); + if (properties != null) { + for (PropertyDefinition propertyDefinition : properties) { + String type = propertyDefinition.getType(); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByName = this.getDataTypeUsingName(type); + if (dataTypeByName.isRight()) { + return Either.right(dataTypeByName.right().value()); + } else { + DataTypeDefinition value = dataTypeByName.left().value(); + if (false == nameToDataTypeDef.containsKey(type)) { + nameToDataTypeDef.put(type, value); + } + } + + } + } + + typeDefinition = typeDefinition.getDerivedFrom(); + } + + return Either.left(nameToDataTypeDef); + } + + public Either<List<ComponentInstanceProperty>, TitanOperationStatus> getAllPropertiesOfResourceInstanceOnlyPropertyDefId(String resourceInstanceUid, NodeTypeEnum instanceNodeType) { + + // Either<ComponentInstanceData, TitanOperationStatus> + // findResInstanceRes = + // titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), + // resourceInstanceUid, ComponentInstanceData.class); + Either<TitanVertex, TitanOperationStatus> findResInstanceRes = titanGenericDao.getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid); + + if (findResInstanceRes.isRight()) { + TitanOperationStatus status = findResInstanceRes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + + // Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, + // TitanOperationStatus> propertyImplNodes = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), + // resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE, + // NodeTypeEnum.PropertyValue, PropertyValueData.class); + Either<List<ImmutablePair<TitanVertex, Edge>>, TitanOperationStatus> propertyImplNodes = titanGenericDao.getChildrenVertecies(UniqueIdBuilder.getKeyByNodeType(instanceNodeType), resourceInstanceUid, GraphEdgeLabels.PROPERTY_VALUE); + + if (propertyImplNodes.isRight()) { + TitanOperationStatus status = propertyImplNodes.right().value(); + return Either.right(status); + } + + List<ImmutablePair<TitanVertex, Edge>> list = propertyImplNodes.left().value(); + if (list == null || true == list.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + List<ComponentInstanceProperty> result = new ArrayList<>(); + for (ImmutablePair<TitanVertex, Edge> propertyValue : list) { + TitanVertex propertyValueDataVertex = propertyValue.getLeft(); + String propertyValueUid = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String value = (String) titanGenericDao.getProperty(propertyValueDataVertex, GraphPropertiesDictionary.VALUE.getProperty()); + + ImmutablePair<TitanVertex, Edge> propertyDefPair = titanGenericDao.getChildVertex(propertyValueDataVertex, GraphEdgeLabels.PROPERTY_IMPL); + if (propertyDefPair == null) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + Map<String, Object> properties = titanGenericDao.getProperties(propertyValueDataVertex); + PropertyValueData propertyValueData = GraphElementFactory.createElement(NodeTypeEnum.PropertyValue.getName(), GraphElementTypeEnum.Node, properties, PropertyValueData.class); + String propertyUniqueId = (String) titanGenericDao.getProperty(propertyDefPair.left, GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + ComponentInstanceProperty resourceInstanceProperty = new ComponentInstanceProperty(); + // set property original unique id + resourceInstanceProperty.setUniqueId(propertyUniqueId); + // set resource id + // TODO: esofer add resource id + resourceInstanceProperty.setParentUniqueId(null); + // set value + resourceInstanceProperty.setValue(value); + // set property value unique id + resourceInstanceProperty.setValueUniqueUid(propertyValueUid); + // set rules + resourceInstanceProperty.setRules(propertyValueData.getRules()); + + result.add(resourceInstanceProperty); + } + + return Either.left(result); + } + + /** + * Find the default value from the list of component instances. Start the search from the second component instance + * + * @param pathOfComponentInstances + * @param propertyUniqueId + * @param defaultValue + * @return + */ + public Either<String, TitanOperationStatus> findDefaultValueFromSecondPosition(List<String> pathOfComponentInstances, String propertyUniqueId, String defaultValue) { + + log.trace("In find default value: path=" + pathOfComponentInstances + "propertyUniqId=" + propertyUniqueId + "defaultValue=" + defaultValue); + + if (pathOfComponentInstances == null || pathOfComponentInstances.size() < 2) { + return Either.left(defaultValue); + } + + String result = defaultValue; + + for (int i = 1; i < pathOfComponentInstances.size(); i++) { + String compInstanceId = pathOfComponentInstances.get(i); + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> propertyValuesResult = this.getAllPropertiesOfResourceInstanceOnlyPropertyDefId(compInstanceId, NodeTypeEnum.ResourceInstance); + + log.trace("After fetching properties values of component instance {}. {}", compInstanceId, propertyValuesResult); + + if (propertyValuesResult.isRight()) { + TitanOperationStatus status = propertyValuesResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + continue; + } + } + + ComponentInstanceProperty foundCompInstanceProperty = fetchByPropertyUid(propertyValuesResult.left().value(), propertyUniqueId); + log.trace("After finding the component instance property on {}. {}", compInstanceId, foundCompInstanceProperty); + + if (foundCompInstanceProperty == null) { + continue; + } + + List<PropertyRule> rules = getOrBuildRulesIfNotExists(pathOfComponentInstances.size() - i, pathOfComponentInstances.get(i), foundCompInstanceProperty.getRules(), foundCompInstanceProperty.getValue()); + + log.trace("Rules of property {} on component instance {} are {}", propertyUniqueId, compInstanceId, rules); + PropertyRule matchedRule = findMatchRule(pathOfComponentInstances, i, rules); + log.trace("Match rule is {}", matchedRule); + + if (matchedRule != null) { + result = matchedRule.getValue(); + break; + } + + } + + return Either.left(result); + + } + + private ComponentInstanceProperty fetchByPropertyUid(List<ComponentInstanceProperty> list, String propertyUniqueId) { + + ComponentInstanceProperty result = null; + + if (list == null) { + return null; + } + + for (ComponentInstanceProperty instProperty : list) { + if (instProperty.getUniqueId().equals(propertyUniqueId)) { + result = instProperty; + break; + } + } + + return result; + } + + private List<PropertyRule> getOrBuildRulesIfNotExists(int ruleSize, String compInstanceId, List<PropertyRule> rules, String value) { + + if (rules != null) { + return rules; + } + + rules = buildDefaultRule(compInstanceId, ruleSize, value); + + return rules; + + } + + private List<PropertyRule> getRulesOfPropertyValue(int size, String instanceId, ComponentInstanceProperty componentInstanceProperty) { + List<PropertyRule> rules = componentInstanceProperty.getRules(); + if (rules == null) { + rules = buildDefaultRule(instanceId, size, componentInstanceProperty.getValue()); + } + return rules; + } + + private List<PropertyRule> buildDefaultRule(String componentInstanceId, int size, String value) { + + List<PropertyRule> rules = new ArrayList<>(); + List<String> rule = new ArrayList<>(); + rule.add(componentInstanceId); + for (int i = 0; i < size - 1; i++) { + rule.add(PropertyRule.RULE_ANY_MATCH); + } + PropertyRule propertyRule = new PropertyRule(rule, value); + rules.add(propertyRule); + + return rules; + + } + + private PropertyRule findMatchRule(List<String> pathOfInstances, int level, List<PropertyRule> rules) { + + PropertyRule propertyRule = null; + + String stringForMatch = buildStringForMatch(pathOfInstances, level); + + String firstCompInstance = pathOfInstances.get(level); + + if (rules != null) { + + for (PropertyRule rule : rules) { + + int ruleSize = rule.getRule().size(); + // check the length of the rule equals to the length of the + // instances path. + if (ruleSize != pathOfInstances.size() - level) { + continue; + } + // check that the rule starts with correct component instance id + if (false == checkFirstItem(firstCompInstance, rule.getFirstToken())) { + continue; + } + + String secondToken = rule.getToken(2); + if (secondToken != null && (secondToken.equals(PropertyRule.FORCE_ALL) || secondToken.equals(PropertyRule.ALL))) { + propertyRule = rule; + break; + } + + String patternStr = buildStringForMatch(rule.getRule(), 0); + + Pattern pattern = Pattern.compile(patternStr); + + Matcher matcher = pattern.matcher(stringForMatch); + + if (matcher.matches()) { + log.trace("{} matches the rule {}", stringForMatch, patternStr); + propertyRule = rule; + break; + } + } + + } + + return propertyRule; + } + + private boolean checkFirstItem(String left, String right) { + if (left != null && left.equals(right)) { + return true; + } + return false; + } + + private String buildStringForMatch(List<String> pathOfInstances, int level) { + StringBuilder builder = new StringBuilder(); + + for (int i = level; i < pathOfInstances.size(); i++) { + builder.append(pathOfInstances.get(i)); + if (i < pathOfInstances.size() - 1) { + builder.append("#"); + } + } + return builder.toString(); + } + + public void updatePropertyByBestMatch(String propertyUniqueId, ComponentInstanceProperty instanceProperty, Map<String, ComponentInstanceProperty> instanceIdToValue) { + + List<String> pathOfInstances = instanceProperty.getPath(); + int level = 0; + int size = pathOfInstances.size(); + int numberOfMatches = 0; + for (String instanceId : pathOfInstances) { + ComponentInstanceProperty componentInstanceProperty = instanceIdToValue.get(instanceId); + + if (componentInstanceProperty != null) { + + List<PropertyRule> rules = getRulesOfPropertyValue(size - level, instanceId, componentInstanceProperty); + // If it is the first level instance, then update valueUniuqeId + // parameter in order to know on update that + // we should update and not create new node on graph. + if (level == 0) { + instanceProperty.setValueUniqueUid(componentInstanceProperty.getValueUniqueUid()); + instanceProperty.setRules(rules); + } + + PropertyRule rule = findMatchRule(pathOfInstances, level, rules); + if (rule != null) { + numberOfMatches++; + String value = rule.getValue(); + if (numberOfMatches == 1) { + instanceProperty.setValue(value); + if (log.isDebugEnabled()) { + log.debug("Set the value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value); + } + } else if (numberOfMatches == 2) { + // In case of another property value match, then use the + // value to be the default value of the property. + instanceProperty.setDefaultValue(value); + if (log.isDebugEnabled()) { + log.debug("Set the default value of property " + propertyUniqueId + " " + instanceProperty.getName() + " on path " + pathOfInstances + " to be " + value); + } + break; + } + } + } + level++; + } + + } + + public void updatePropertiesByPropertyValues(Map<String, List<ComponentInstanceProperty>> resourceInstancesProperties, Map<String, Map<String, ComponentInstanceProperty>> values) { + + if (resourceInstancesProperties == null) { + return; + } + + List<ComponentInstanceProperty> allProperties = new ArrayList<>(); + Collection<List<ComponentInstanceProperty>> properties = resourceInstancesProperties.values(); + if (properties != null) { + Iterator<List<ComponentInstanceProperty>> iterator = properties.iterator(); + while (iterator.hasNext()) { + List<ComponentInstanceProperty> compInstancePropertyList = iterator.next(); + allProperties.addAll(compInstancePropertyList); + } + } + + // Go over each property and check whether there is a rule which updates + // it + for (ComponentInstanceProperty instanceProperty : allProperties) { + + String propertyUniqueId = instanceProperty.getUniqueId(); + + // get the changes per componentInstanceId. + Map<String, ComponentInstanceProperty> instanceIdToValue = values.get(propertyUniqueId); + + if (instanceIdToValue == null) { + continue; + } + + this.updatePropertyByBestMatch(propertyUniqueId, instanceProperty, instanceIdToValue); + + } + + } + + /** + * + * Add data type to graph. + * + * 1. Add data type node + * + * 2. Add edge between the former node to its parent(if exists) + * + * 3. Add property node and associate it to the node created at #1. (per property & if exists) + * + * @param dataTypeDefinition + * @return + */ + private Either<DataTypeData, TitanOperationStatus> addDataTypeToGraph(DataTypeDefinition dataTypeDefinition) { + + log.debug("Got data type " + dataTypeDefinition); + + String dtUniqueId = UniqueIdBuilder.buildDataTypeUid(dataTypeDefinition.getName()); + + DataTypeData dataTypeData = buildDataTypeData(dataTypeDefinition, dtUniqueId); + + log.debug("Before adding data type to graph. dataTypeData = " + dataTypeData); + Either<DataTypeData, TitanOperationStatus> createDataTypeResult = titanGenericDao.createNode(dataTypeData, DataTypeData.class); + log.debug("After adding data type to graph. status is = {}", createDataTypeResult); + + if (createDataTypeResult.isRight()) { + TitanOperationStatus operationStatus = createDataTypeResult.right().value(); + log.debug("Failed to data type " + dataTypeDefinition.getName() + " to graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", NodeTypeEnum.DataType.getName()); + return Either.right(operationStatus); + } + + DataTypeData resultCTD = createDataTypeResult.left().value(); + List<PropertyDefinition> properties = dataTypeDefinition.getProperties(); + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(resultCTD.getUniqueId(), properties); + if (addPropertiesToDataType.isRight()) { + log.debug("Failed add properties " + properties + " to data type " + dataTypeDefinition.getName()); + return Either.right(addPropertiesToDataType.right().value()); + } + + String derivedFrom = dataTypeDefinition.getDerivedFromName(); + if (derivedFrom != null) { + log.debug("Before creating relation between data type " + dtUniqueId + " to its parent " + derivedFrom); + UniqueIdData from = new UniqueIdData(NodeTypeEnum.DataType, dtUniqueId); + + String deriveFromUid = UniqueIdBuilder.buildDataTypeUid(derivedFrom); + UniqueIdData to = new UniqueIdData(NodeTypeEnum.DataType, deriveFromUid); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(from, to, GraphEdgeLabels.DERIVED_FROM, null); + log.debug("After create relation between capability type " + dtUniqueId + " to its parent " + derivedFrom + ". status is " + createRelation); + if (createRelation.isRight()) { + return Either.right(createRelation.right().value()); + } + } + + return Either.left(createDataTypeResult.left().value()); + + } + + private DataTypeData buildDataTypeData(DataTypeDefinition dataTypeDefinition, String ctUniqueId) { + + DataTypeData dataTypeData = new DataTypeData(dataTypeDefinition); + + dataTypeData.getDataTypeDataDefinition().setUniqueId(ctUniqueId); + Long creationDate = dataTypeData.getDataTypeDataDefinition().getCreationTime(); + if (creationDate == null) { + creationDate = System.currentTimeMillis(); + } + dataTypeData.getDataTypeDataDefinition().setCreationTime(creationDate); + dataTypeData.getDataTypeDataDefinition().setModificationTime(creationDate); + + return dataTypeData; + } + + /** + * add properties to capability type. + * + * Per property, add a property node and associate it to the capability type + * + * @param uniqueId + * @param properties + * @return + */ + private Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType(String uniqueId, List<PropertyDefinition> properties) { + + Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>(); + + if (properties != null && false == properties.isEmpty()) { + for (PropertyDefinition propertyDefinition : properties) { + String propertyName = propertyDefinition.getName(); + + String propertyType = propertyDefinition.getType(); + Either<Boolean, TitanOperationStatus> validPropertyType = isValidPropertyType(propertyType); + if (validPropertyType.isRight()) { + log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType); + return Either.right(validPropertyType.right().value()); + } + Boolean isValid = validPropertyType.left().value(); + if (isValid == null || isValid.booleanValue() == false) { + log.debug("Data type " + uniqueId + " contains invalid property type " + propertyType); + return Either.right(TitanOperationStatus.INVALID_TYPE); + } + + Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinition, NodeTypeEnum.DataType, uniqueId); + if (addPropertyToNodeType.isRight()) { + TitanOperationStatus operationStatus = addPropertyToNodeType.right().value(); + log.debug("Failed to associate data type " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to associate property to data type. Status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } + propertiesData.put(propertyName, addPropertyToNodeType.left().value()); + } + + DataTypeData dataTypeData = new DataTypeData(); + dataTypeData.getDataTypeDataDefinition().setUniqueId(uniqueId); + long modificationTime = System.currentTimeMillis(); + dataTypeData.getDataTypeDataDefinition().setModificationTime(modificationTime); + + Either<DataTypeData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(dataTypeData, DataTypeData.class); + if (updateNode.isRight()) { + TitanOperationStatus operationStatus = updateNode.right().value(); + log.debug("Failed to update modification time data type " + uniqueId + " from graph. status is " + operationStatus); + BeEcompErrorManager.getInstance().logInternalFlowError("AddPropertyToDataType", "Failed to fetch data type. Status is " + operationStatus, ErrorSeverity.ERROR); + return Either.right(operationStatus); + } else { + log.debug("Update data type uid {}. Set modification time to {}", uniqueId, modificationTime); + } + + } + + return Either.left(propertiesData); + + } + + /** + * Build Data type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUid(String uniqueId) { + + Either<DataTypeDefinition, TitanOperationStatus> result = null; + + Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType, + DataTypeData.class); + log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value(); + DataTypeData parentCT = immutablePair.getKey(); + + String parentUniqueId = parentCT.getUniqueId(); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId); + + if (dataTypeByUid.isRight()) { + return Either.right(dataTypeByUid.right().value()); + } + + DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value(); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + } + result = Either.left(dataTypeDefinition); + + return result; + } + + private TitanOperationStatus fillProperties(String uniqueId, DataTypeDefinition dataTypeDefinition) { + + Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.DataType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value(); + if (properties != null && properties.isEmpty() == false) { + List<PropertyDefinition> listOfProps = new ArrayList<>(); + + for (Entry<String, PropertyDefinition> entry : properties.entrySet()) { + String propName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition); + newPropertyDefinition.setName(propName); + listOfProps.add(newPropertyDefinition); + } + dataTypeDefinition.setProperties(listOfProps); + } + return TitanOperationStatus.OK; + } + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition, boolean inTransaction) { + + Either<DataTypeDefinition, StorageOperationStatus> result = null; + + try { + + Either<DataTypeData, TitanOperationStatus> eitherStatus = addDataTypeToGraph(dataTypeDefinition); + + if (eitherStatus.isRight()) { + log.debug("Failed to add data type {} to Graph. status is {}", dataTypeDefinition, eitherStatus.right().value().name()); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("AddDataType", "DataType"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(eitherStatus.right().value())); + return result; + } else { + DataTypeData capabilityTypeData = eitherStatus.left().value(); + + DataTypeDefinition dataTypeDefResult = convertDTDataToDTDefinition(capabilityTypeData); + log.debug("The returned CapabilityTypeDefinition is " + dataTypeDefResult); + result = Either.left(dataTypeDefResult); + return result; + } + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> addDataType(DataTypeDefinition dataTypeDefinition) { + return addDataType(dataTypeDefinition, true); + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name, boolean inTransaction) { + + Either<DataTypeDefinition, StorageOperationStatus> result = null; + try { + + String dtUid = UniqueIdBuilder.buildDataTypeUid(name); + Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUid(dtUid); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type " + name + "status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByName(String name) { + return getDataTypeByName(name, true); + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name) { + return getDataTypeByNameWithoutDerived(name, true); + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> getDataTypeByNameWithoutDerived(String name, boolean inTransaction) { + + Either<DataTypeDefinition, StorageOperationStatus> result = null; + try { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + Either<DataTypeDefinition, TitanOperationStatus> ctResult = this.getDataTypeByUidWithoutDerivedDataTypes(uid); + + if (ctResult.isRight()) { + TitanOperationStatus status = ctResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to retrieve information on capability type " + name + "status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(ctResult.right().value())); + return result; + } + + result = Either.left(ctResult.left().value()); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByUidWithoutDerivedDataTypes(String uniqueId) { + + Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + return Either.left(dataTypeDefinition); + } + + public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeByNameWithoutDerivedDataTypes(String name) { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + return getDataTypeByUidWithoutDerivedDataTypes(uid); + + } + + /** + * + * convert between graph Node object to Java object + * + * @param dataTypeData + * @return + */ + protected DataTypeDefinition convertDTDataToDTDefinition(DataTypeData dataTypeData) { + log.debug("The object returned after create data type is " + dataTypeData); + + DataTypeDefinition dataTypeDefResult = new DataTypeDefinition(dataTypeData.getDataTypeDataDefinition()); + + return dataTypeDefResult; + } + + private Either<Boolean, TitanOperationStatus> isValidPropertyType(String propertyType) { + + if (propertyType == null || propertyType.isEmpty()) { + return Either.left(false); + } + + ToscaPropertyType toscaPropertyType = ToscaPropertyType.isValidType(propertyType); + if (toscaPropertyType == null) { + Either<Boolean, TitanOperationStatus> definedInDataTypes = isDefinedInDataTypes(propertyType); + return definedInDataTypes; + } else { + return Either.left(true); + } + } + + private Either<Boolean, TitanOperationStatus> isDefinedInDataTypes(String propertyType) { + + String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return Either.left(false); + } + return Either.right(status); + } + + return Either.left(true); + + } + + private Either<DataTypeDefinition, TitanOperationStatus> getExternalDataType(String propertyType) { + + String dataTypeUid = UniqueIdBuilder.buildDataTypeUid(propertyType); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(dataTypeUid); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + return Either.right(status); + } + + return Either.left(dataTypeByUid.left().value()); + + } + + public Either<Map<String, DataTypeDefinition>, TitanOperationStatus> getAllDataTypes() { + + Map<String, DataTypeDefinition> dataTypes = new HashMap<>(); + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> result = Either.left(dataTypes); + + Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class); + if (getAllDataTypes.isRight()) { + TitanOperationStatus status = getAllDataTypes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(status); + } else { + return result; + } + } + + List<DataTypeData> list = getAllDataTypes.left().value(); + if (list != null) { + + log.trace("Number of data types to load is " + list.size()); + + List<String> collect = list.stream().map(p -> p.getDataTypeDataDefinition().getName()).collect(Collectors.toList()); + log.trace("The data types to load are " + collect); + + for (DataTypeData dataTypeData : list) { + + log.trace("Going to fetch data type " + dataTypeData.getDataTypeDataDefinition().getName() + ". uid is " + dataTypeData.getUniqueId()); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getAndAddDataTypeByUid(dataTypeData.getUniqueId(), dataTypes); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = dataTypeByUid.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.INVALID_ID; + } + return Either.right(status); + } + } + } + + if (log.isTraceEnabled()) { + if (result.isRight()) { + log.trace("After fetching all data types " + result); + } else { + Map<String, DataTypeDefinition> map = result.left().value(); + if (map != null) { + String types = map.keySet().stream().collect(Collectors.joining(",", "[", "]")); + log.trace("After fetching all data types " + types); + } + } + } + + return result; + } + + /** + * Build Data type object from graph by unique id + * + * @param uniqueId + * @return + */ + public Either<DataTypeDefinition, TitanOperationStatus> getAndAddDataTypeByUid(String uniqueId, Map<String, DataTypeDefinition> allDataTypes) { + + Either<DataTypeDefinition, TitanOperationStatus> result = null; + + if (allDataTypes.containsKey(uniqueId)) { + return Either.left(allDataTypes.get(uniqueId)); + } + + Either<DataTypeData, TitanOperationStatus> dataTypesRes = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, DataTypeData.class); + + if (dataTypesRes.isRight()) { + TitanOperationStatus status = dataTypesRes.right().value(); + log.debug("Data type " + uniqueId + " cannot be found in graph. status is " + status); + return Either.right(status); + } + + DataTypeData ctData = dataTypesRes.left().value(); + DataTypeDefinition dataTypeDefinition = new DataTypeDefinition(ctData.getDataTypeDataDefinition()); + + TitanOperationStatus propertiesStatus = fillProperties(uniqueId, dataTypeDefinition); + if (propertiesStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of data type " + uniqueId); + return Either.right(propertiesStatus); + } + + allDataTypes.put(dataTypeDefinition.getName(), dataTypeDefinition); + + String derivedFrom = dataTypeDefinition.getDerivedFromName(); + if (allDataTypes.containsKey(derivedFrom)) { + DataTypeDefinition parentDataTypeDefinition = allDataTypes.get(derivedFrom); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + return Either.left(dataTypeDefinition); + } + + Either<ImmutablePair<DataTypeData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.DataType), uniqueId, GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.DataType, + DataTypeData.class); + log.debug("After retrieving DERIVED_FROM node of " + uniqueId + ". status is " + parentNode); + if (parentNode.isRight()) { + TitanOperationStatus titanOperationStatus = parentNode.right().value(); + if (titanOperationStatus != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the parent data type of data type " + uniqueId + ". status is " + titanOperationStatus); + result = Either.right(titanOperationStatus); + return result; + } + } else { + // derived from node was found + ImmutablePair<DataTypeData, GraphEdge> immutablePair = parentNode.left().value(); + DataTypeData parentCT = immutablePair.getKey(); + + String parentUniqueId = parentCT.getUniqueId(); + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(parentUniqueId); + + if (dataTypeByUid.isRight()) { + return Either.right(dataTypeByUid.right().value()); + } + + DataTypeDefinition parentDataTypeDefinition = dataTypeByUid.left().value(); + + dataTypeDefinition.setDerivedFrom(parentDataTypeDefinition); + + } + result = Either.left(dataTypeDefinition); + + return result; + } + + public Either<DataTypeDefinition, TitanOperationStatus> getDataTypeUsingName(String name) { + + String uid = UniqueIdBuilder.buildDataTypeUid(name); + + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = getDataTypeByUid(uid); + + return dataTypeByUid; + } + + public Either<String, TitanOperationStatus> checkInnerType(PropertyDataDefinition propDataDef) { + + String propertyType = propDataDef.getType(); + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + Either<String, TitanOperationStatus> result = getInnerType(type, () -> propDataDef.getSchema()); + + return result; + } + + public Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypeNodes() { + Either<List<DataTypeData>, TitanOperationStatus> getAllDataTypes = titanGenericDao.getByCriteria(NodeTypeEnum.DataType, null, DataTypeData.class); + if (getAllDataTypes.isRight()) { + TitanOperationStatus status = getAllDataTypes.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + status = TitanOperationStatus.OK; + return Either.right(status); + } + } + return getAllDataTypes; + } + + public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, boolean isValidate, String innerType, Map<String, DataTypeDefinition> dataTypes) { + log.trace("Going to validate property value and its type. type = {}, value = {}", propertyType, value); + ToscaPropertyType type = getType(propertyType); + + if (isValidate) { + + if (type == null) { + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + ImmutablePair<JsonElement, Boolean> validateResult = dataTypeValidatorConverter.validateAndUpdate(value, dataTypeDefinition, dataTypes); + if (validateResult.right.booleanValue() == false) { + log.debug("The value {} of property from type {} is invalid", value, propertyType); + return Either.right(false); + } + JsonElement jsonElement = validateResult.left; + String valueFromJsonElement = getValueFromJsonElement(jsonElement); + return Either.left(valueFromJsonElement); + } + log.trace("before validating property type {}", propertyType); + boolean isValidProperty = isValidValue(type, value, innerType, dataTypes); + if (false == isValidProperty) { + log.debug("The value {} of property from type {} is invalid", value, type); + return Either.right(false); + } + } + Object convertedValue = value; + if (false == isEmptyValue(value) && isValidate) { + PropertyValueConverter converter = type.getConverter(); + convertedValue = converter.convert(value, innerType, dataTypes); + } + return Either.left(convertedValue); + } + + public Either<Object, Boolean> validateAndUpdatePropertyValue(String propertyType, String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return validateAndUpdatePropertyValue(propertyType, value, true, innerType, dataTypes); + } + + /* + * @Override public PropertyOperation getPropertyOperation() { return this; } + */ + protected TitanOperationStatus fillProperties(String uniqueId, Consumer<List<PropertyDefinition>> propertySetter) { + Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfNode = this.findPropertiesOfNode(NodeTypeEnum.GroupType, uniqueId); + if (findPropertiesOfNode.isRight()) { + TitanOperationStatus titanOperationStatus = findPropertiesOfNode.right().value(); + log.debug("After looking for properties of vertex " + uniqueId + ". status is " + titanOperationStatus); + if (TitanOperationStatus.NOT_FOUND.equals(titanOperationStatus)) { + return TitanOperationStatus.OK; + } else { + return titanOperationStatus; + } + } else { + Map<String, PropertyDefinition> properties = findPropertiesOfNode.left().value(); + + if (properties != null) { + List<PropertyDefinition> propertiesAsList = properties.entrySet().stream().map(p -> p.getValue()).collect(Collectors.toList()); + propertySetter.accept(propertiesAsList); + } + + return TitanOperationStatus.OK; + } + } + + /** + * add properties to element type. + * + * Per property, add a property node and associate it to the element type + * + * @param uniqueId + * @param propertiesMap + * TODO + * @return + */ + protected Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap) { + + Map<String, PropertyData> propertiesData = new HashMap<String, PropertyData>(); + + if (propertiesMap != null) { + + for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) { + String propertyName = propertyDefinitionEntry.getKey(); + + Either<PropertyData, TitanOperationStatus> addPropertyToNodeType = this.addPropertyToNodeType(propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId); + + if (addPropertyToNodeType.isRight()) { + TitanOperationStatus operationStatus = addPropertyToNodeType.right().value(); + log.error("Failed to associate " + nodeType.getName() + " " + uniqueId + " to property " + propertyName + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + propertiesData.put(propertyName, addPropertyToNodeType.left().value()); + + } + } + + return Either.left(propertiesData); + + } + + protected TitanOperationStatus addPropertiesToElementType(String uniqueId, NodeTypeEnum nodeType, Map<String, PropertyDefinition> propertiesMap, TitanVertex elementVertex) { + + if (propertiesMap != null) { + + for (Entry<String, PropertyDefinition> propertyDefinitionEntry : propertiesMap.entrySet()) { + String propertyName = propertyDefinitionEntry.getKey(); + + TitanOperationStatus operationStatus = this.addPropertyToNodeType(elementVertex, propertyName, propertyDefinitionEntry.getValue(), nodeType, uniqueId); + + if (!operationStatus.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate {} {} to property {} in graph. status is {}", nodeType.getName(), uniqueId, propertyName, operationStatus); + return operationStatus; + } + } + } + + return TitanOperationStatus.OK; + + } + + public Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToElementType(String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) { + + Map<String, PropertyDefinition> propMap; + if (properties == null) { + propMap = null; + } else { + propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef)); + } + return addPropertiesToElementType(uniqueId, elementType, propMap); + } + + public TitanOperationStatus addPropertiesToElementType(TitanVertex elementVertex, String uniqueId, NodeTypeEnum elementType, List<PropertyDefinition> properties) { + + Map<String, PropertyDefinition> propMap; + if (properties == null) { + propMap = null; + } else { + propMap = properties.stream().collect(Collectors.toMap(propDef -> propDef.getName(), propDef -> propDef)); + } + return addPropertiesToElementType(uniqueId, elementType, propMap, elementVertex); + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition) { + return updateDataType(newDataTypeDefinition, oldDataTypeDefinition, true); + } + + @Override + public Either<DataTypeDefinition, StorageOperationStatus> updateDataType(DataTypeDefinition newDataTypeDefinition, DataTypeDefinition oldDataTypeDefinition, boolean inTransaction) { + + Either<DataTypeDefinition, StorageOperationStatus> result = null; + + try { + + List<PropertyDefinition> newProperties = newDataTypeDefinition.getProperties(); + + List<PropertyDefinition> oldProperties = oldDataTypeDefinition.getProperties(); + + String newDerivedFromName = getDerivedFromName(newDataTypeDefinition); + + String oldDerivedFromName = getDerivedFromName(oldDataTypeDefinition); + + String dataTypeName = newDataTypeDefinition.getName(); + + List<PropertyDefinition> propertiesToAdd = new ArrayList<>(); + if (isPropertyOmitted(newProperties, oldProperties, dataTypeName) || isPropertyTypeChanged(dataTypeName, newProperties, oldProperties, propertiesToAdd) || isDerivedFromNameChanged(dataTypeName, newDerivedFromName, oldDerivedFromName)) { + + log.debug("The new data type " + dataTypeName + " is invalid."); + + result = Either.right(StorageOperationStatus.CANNOT_UPDATE_EXISTING_ENTITY); + return result; + } + + if (propertiesToAdd == null || propertiesToAdd.isEmpty()) { + log.debug("No new properties has been defined in the new data type " + newDataTypeDefinition); + result = Either.right(StorageOperationStatus.OK); + return result; + } + + Either<Map<String, PropertyData>, TitanOperationStatus> addPropertiesToDataType = addPropertiesToDataType(oldDataTypeDefinition.getUniqueId(), propertiesToAdd); + + if (addPropertiesToDataType.isRight()) { + log.debug("Failed to update data type {} to Graph. Status is {}", oldDataTypeDefinition, addPropertiesToDataType.right().value().name()); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("UpdateDataType", "Property"); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropertiesToDataType.right().value())); + return result; + } else { + + Either<DataTypeDefinition, TitanOperationStatus> dataTypeByUid = this.getDataTypeByUid(oldDataTypeDefinition.getUniqueId()); + if (dataTypeByUid.isRight()) { + TitanOperationStatus status = addPropertiesToDataType.right().value(); + log.debug("Failed to get data type {} after update. Status is {}", oldDataTypeDefinition.getUniqueId(), status.name()); + BeEcompErrorManager.getInstance().logBeFailedRetrieveNodeError("UpdateDataType", "Property", status.name()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + result = Either.left(dataTypeByUid.left().value()); + } + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private String getDerivedFromName(DataTypeDefinition dataTypeDefinition) { + String derivedFromName = dataTypeDefinition.getDerivedFromName(); + // if (derivedFromName == null) { + // DataTypeDefinition derivedFrom = dataTypeDefinition.getDerivedFrom(); + // if (derivedFrom != null) { + // log.debug("Dervied from is taken from definition"); + // derivedFromName = derivedFrom.getName(); + // } + // } else { + // log.debug("Dervied from is taken from field derivedFromName"); + // } + return derivedFromName; + } + + private boolean isPropertyTypeChanged(String dataTypeName, List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, List<PropertyDefinition> outputPropertiesToAdd) { + + if (newProperties != null && oldProperties != null) { + + Map<String, PropertyDefinition> newPropsMapper = newProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p)); + Map<String, PropertyDefinition> oldPropsMapper = oldProperties.stream().collect(Collectors.toMap(p -> p.getName(), p -> p)); + + for (Entry<String, PropertyDefinition> newPropertyEntry : newPropsMapper.entrySet()) { + + String propName = newPropertyEntry.getKey(); + PropertyDefinition propDef = newPropertyEntry.getValue(); + + PropertyDefinition oldPropertyDefinition = oldPropsMapper.get(propName); + if (oldPropertyDefinition == null) { + log.debug("New property {} received in the data type {}", propName, dataTypeName); + outputPropertiesToAdd.add(propDef); + continue; + } + + String oldType = oldPropertyDefinition.getType(); + String oldEntryType = getEntryType(oldPropertyDefinition); + + String newType = propDef.getType(); + String newEntryType = getEntryType(propDef); + + if (false == oldType.equals(newType)) { + log.debug("Existing property {} in data type {} has a differnet type {} than the new one {}", propName, dataTypeName, oldType, newType); + return true; + } + + if (false == equalsEntryTypes(oldEntryType, newEntryType)) { + log.debug("Existing property {} in data type {} has a differnet entry type {} than the new one {}", propName, dataTypeName, oldEntryType, newEntryType); + return true; + } + + } + + } + + return false; + } + + private boolean equalsEntryTypes(String oldEntryType, String newEntryType) { + + if (oldEntryType == null && newEntryType == null) { + return true; + } else if (oldEntryType != null && newEntryType != null) { + return oldEntryType.equals(newEntryType); + } else { + return false; + } + } + + private String getEntryType(PropertyDefinition oldPropertyDefinition) { + String entryType = null; + SchemaDefinition schema = oldPropertyDefinition.getSchema(); + if (schema != null) { + PropertyDataDefinition schemaProperty = schema.getProperty(); + if (schemaProperty != null) { + entryType = schemaProperty.getType(); + } + } + return entryType; + } + + private boolean isPropertyOmitted(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) { + + boolean isValid = validateChangeInCaseOfEmptyProperties(newProperties, oldProperties, dataTypeName); + if (false == isValid) { + log.debug("At least one property is missing in the new data type {}", dataTypeName); + return false; + } + + if (newProperties != null && oldProperties != null) { + + List<String> newProps = newProperties.stream().map(p -> p.getName()).collect(Collectors.toList()); + List<String> oldProps = oldProperties.stream().map(p -> p.getName()).collect(Collectors.toList()); + + if (false == newProps.containsAll(oldProps)) { + StringJoiner joiner = new StringJoiner(",", "[", "]"); + newProps.forEach(p -> joiner.add(p)); + log.debug("Properties {} in data type {} are missing, but they already defined in the existing data type", joiner.toString(), dataTypeName); + return true; + } + + } + return false; + } + + private boolean validateChangeInCaseOfEmptyProperties(List<PropertyDefinition> newProperties, List<PropertyDefinition> oldProperties, String dataTypeName) { + + if (newProperties != null) { + if (newProperties.isEmpty()) { + newProperties = null; + } + } + + if (oldProperties != null) { + if (oldProperties.isEmpty()) { + oldProperties = null; + } + } + + if ((newProperties == null && oldProperties == null) || (newProperties != null && oldProperties != null)) { + return true; + } + + return false; + } + + private boolean isDerivedFromNameChanged(String dataTypeName, String newDerivedFromName, String oldDerivedFromName) { + + if (newDerivedFromName != null) { + boolean isEqual = newDerivedFromName.equals(oldDerivedFromName); + if (false == isEqual) { + log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName); + } + return !isEqual; + } else if (oldDerivedFromName == null) { + return false; + } else {// new=null, old != null + log.debug("The new datatype {} derived from another data type {} than the existing one {}", dataTypeName, newDerivedFromName, oldDerivedFromName); + return true; + } + + } + + /** + * + * Future - unfinished + * + * @param type + * @param value + * @return + */ + public boolean isValueToscaFunction(String type, String value) { + + boolean result = false; + + if (ToscaPropertyType.STRING.getType().equals(type) || isScalarDerivedFromString(type)) { + + } + + String[] functions = { "get_input" }; + + if (value != null) { + + for (String function : functions) { + + } + + } + + return result; + + } + + /** + * Future - unfinished + * + * @param type + * @return + */ + private boolean isScalarDerivedFromString(String type) { + // TODO Auto-generated method stub + return false; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java new file mode 100644 index 0000000000..e8892ad333 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java @@ -0,0 +1,1674 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import com.thinkaurelius.titan.core.TitanTransaction; +import com.thinkaurelius.titan.core.TitanVertex; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.CapabiltyInstance; +import org.openecomp.sdc.be.model.Point; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.RequirementImplDef; +import org.openecomp.sdc.be.model.operations.api.IRequirementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.CapabilityTypeData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.RequirementImplData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("requirement-operation") +public class RequirementOperation implements IRequirementOperation { + + private static final String NA = "NA"; + + private static final String EQUAL_SIGN = "="; + + private static final String EMPTY_STRING = ""; + + public RequirementOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(RequirementOperation.class.getName()); + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private CapabilityTypeOperation capabilityTypeOperation; + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + protected CapabilityTypeDefinition convertCTDataToCTDefinition(CapabilityTypeData capabilityTypeData) { + log.debug("The object returned after create capability is " + capabilityTypeData); + + CapabilityTypeDefinition capabilityTypeDefResult = new CapabilityTypeDefinition( + capabilityTypeData.getCapabilityTypeDataDefinition()); + + return capabilityTypeDefResult; + } + + /** + * FOR TEST ONLY + * + * @param capabilityOperation + */ + public void setCapabilityOperation(CapabilityOperation capabilityOperation) { + this.capabilityOperation = capabilityOperation; + } + + public void setCapabilityTypeOperation(CapabilityTypeOperation capabilityTypeOperation) { + this.capabilityTypeOperation = capabilityTypeOperation; + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId) { + + return addRequirementToResource(reqName, reqDefinition, resourceId, false); + } + + private Either<GraphRelation, TitanOperationStatus> associateRequirementToRelationshipType(RequirementData reqData, + RequirementDefinition reqDefinition) { + + String relationship = reqDefinition.getRelationship(); + + if (relationship == null) { + log.debug("The provided relationship is null."); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.RelationshipType, relationship); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqData, + uniqueIdData, GraphEdgeLabels.RELATIONSHIP_TYPE, null); + + return createRelation; + + } + + /** + * Associate the requirement node to its capability type + * + * @param reqData + * @param reqDefinition + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateRequirementToCapabilityType(RequirementData reqData, + RequirementDefinition reqDefinition) { + + String capability = reqDefinition.getCapability(); + + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqData, + uniqueIdData, GraphEdgeLabels.CAPABILITY_TYPE, null); + + log.debug("After associating requirementData " + reqData + " to capability " + capability + ". status is " + + createRelation); + + return createRelation; + } + + private TitanOperationStatus associateRequirementToCapabilityType(TitanVertex reqData, + RequirementDefinition reqDefinition) { + + String capability = reqDefinition.getCapability(); + + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.CapabilityType, capability); + TitanOperationStatus createRelation = titanGenericDao.createEdge(reqData, uniqueIdData, + GraphEdgeLabels.CAPABILITY_TYPE, null); + + log.debug("After associating requirementData {} to capability {}. status is {}" + reqData, capability, + createRelation); + + return createRelation; + } + + /** + * Associate requirement impl node to capability instance node + * + * @param reqImplData + * @param capabilityInstData + * @param capabilityName + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateRequirementImplToCapabilityInst( + RequirementImplData reqImplData, CapabilityInstData capabilityInstData, String capabilityName) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), capabilityName); + + log.debug( + "Before associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(reqImplData, + capabilityInstData, GraphEdgeLabels.CAPABILITY_INST, props); + log.debug("After associating requirement impl " + reqImplData + " to capability instance " + capabilityInstData + + ".status is " + createRelation); + + return createRelation; + + } + + /** + * Add requirement node to graph + * + * @param resourceId + * @param reqName + * @param reqDefinition + * @return + */ + private Either<RequirementData, TitanOperationStatus> addRequirementData(String resourceId, String reqName, + RequirementDefinition reqDefinition) { + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceId); + + RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition); + + log.debug("Before adding requirement data to graph {}", requirementData); + Either<RequirementData, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(requirementData, + RequirementData.class); + + log.debug("After adding requirement to graph {}", requirementData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, resourceData, + requirementData); + if (status != TitanOperationStatus.OK) { + return Either.right(status); + } + + return Either.left(createNodeResult.left().value()); + + } + + private Either<TitanVertex, TitanOperationStatus> addRequirementData(TitanVertex vertex, String resourceId, + String reqName, RequirementDefinition reqDefinition) { + + RequirementData requirementData = buildRequirementData(resourceId, reqName, reqDefinition); + + log.debug("Before adding requirement data to graph {}", requirementData); + Either<TitanVertex, TitanOperationStatus> createNodeResult = titanGenericDao.createNode(requirementData); + + log.debug("After adding requirement to graph {}", requirementData); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementData + " ] " + " to graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + TitanOperationStatus status = associateResourceDataToRequirementData(resourceId, reqName, vertex, + createNodeResult.left().value()); + if (!status.equals(TitanOperationStatus.OK)) { + return Either.right(status); + } + return Either.left(createNodeResult.left().value()); + } + + /** + * Asssociate resource node to requirement node with REQUIREMENT label and + * requirement name as property on the edge. + * + * @param resourceId + * @param reqName + * @param resourceData + * @param requirementData + * @return + */ + private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName, + ResourceMetadataData resourceData, RequirementData requirementData) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resourceData, + requirementData, GraphEdgeLabels.REQUIREMENT, props); + log.debug("After creatin edge between resource " + resourceId + " to requirement " + requirementData); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource " + resourceId + " to requirement " + reqName + "[ " + + requirementData + "] in graph. status is " + operationStatus); + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus associateResourceDataToRequirementData(String resourceId, String reqName, + TitanVertex resourceVertex, TitanVertex requirementVertex) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + TitanOperationStatus createRelResult = titanGenericDao.createEdge(resourceVertex, requirementVertex, + GraphEdgeLabels.REQUIREMENT, props); + log.debug("After creatin edge between resource {} to requirement {}", resourceId, requirementVertex); + if (!createRelResult.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate resource {} to requirement {} in graph. status is " + resourceId, reqName, + createRelResult); + } + return TitanOperationStatus.OK; + } + + private RequirementData buildRequirementData(String resourceId, String reqName, + RequirementDefinition reqDefinition) { + + RequirementData requirementData = new RequirementData(); + requirementData.setNode(reqDefinition.getNode()); + requirementData.setUniqueId(UniqueIdBuilder.buildRequirementUid(resourceId, reqName)); + Long creationTime = System.currentTimeMillis(); + requirementData.setCreationTime(creationTime); + requirementData.setModificationTime(creationTime); + requirementData.setRelationshipType(reqDefinition.getRelationship()); + requirementData.setMinOccurrences(reqDefinition.getMinOccurrences()); + requirementData.setMaxOccurrences(reqDefinition.getMaxOccurrences()); + + return requirementData; + } + + /** + * build requirement impl node associate it to resource, requirement & + * implementation resource + * + * [RESOURCE] --> [REQUIREMENT IMPL] --> [ RESOURCE IMPL ] | V [REQUIREMENT] + * + * @param resourceLabel + * @param resourceId + * @param reqName + * @param requirementUid + * @param reqImplDefinition + * @return + */ + private Either<RequirementImplData, TitanOperationStatus> addRequirementImplData(NodeTypeEnum resourceLabel, + String resourceId, String reqName, String requirementUid, RequirementImplDef reqImplDefinition) { + + RequirementImplData requirementImplData = buildRequirementImplData(resourceId, reqName, reqImplDefinition); + + log.debug("Before adding requirement impl data to graph " + requirementImplData); + Either<RequirementImplData, TitanOperationStatus> createNodeResult = titanGenericDao + .createNode(requirementImplData, RequirementImplData.class); + log.debug("After adding requirement to graph " + requirementImplData + ". status is " + createNodeResult); + if (createNodeResult.isRight()) { + TitanOperationStatus operationStatus = createNodeResult.right().value(); + log.error("Failed to add requirement " + reqName + " [ " + requirementImplData + " ] " + + " to graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Either<GraphRelation, TitanOperationStatus> createRelResult = associateReqImplRoResource(resourceLabel, + resourceId, reqName, requirementImplData); + if (createRelResult.isRight()) { + TitanOperationStatus operationStatus = createRelResult.right().value(); + log.error("Failed to associate resource " + resourceId + " to requirement impl " + requirementImplData + + "[ " + requirementImplData + "] in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + Either<GraphRelation, TitanOperationStatus> associateToResourceImpl = associateReqImplToImplResource( + requirementImplData, reqImplDefinition.getNodeId()); + if (associateToResourceImpl.isRight()) { + TitanOperationStatus operationStatus = associateToResourceImpl.right().value(); + log.error("Failed to associate requirement impl " + requirementImplData + " to resource impl " + + reqImplDefinition.getNodeId() + "[ " + requirementImplData + "] in graph. status is " + + operationStatus); + return Either.right(operationStatus); + } + + Either<GraphRelation, TitanOperationStatus> associateToRequirement = associateReqImplToRequirement( + requirementImplData, requirementUid); + if (associateToRequirement.isRight()) { + TitanOperationStatus operationStatus = associateToRequirement.right().value(); + log.error("Failed to associate requirement impl " + requirementImplData + " to requirement " + reqName + + " in graph. status is " + operationStatus); + return Either.right(operationStatus); + } + + return Either.left(createNodeResult.left().value()); + + } + + private RequirementImplData buildRequirementImplData(String resourceId, String reqName, + RequirementImplDef reqImplDefinition) { + String reqImplUid = UniqueIdBuilder.buildRequirementImplUid(resourceId, reqName); + RequirementImplData requirementImplData = new RequirementImplData(); + requirementImplData.setName(reqName); + requirementImplData.setUniqueId(reqImplUid); + Long creationTime = System.currentTimeMillis(); + requirementImplData.setCreationTime(creationTime); + requirementImplData.setModificationTime(creationTime); + Point point = reqImplDefinition.getPoint(); + if (point != null) { + requirementImplData.setPosX(point.getX()); + requirementImplData.setPosY(point.getY()); + } + return requirementImplData; + } + + /** + * associate requirement impl node to the source requirement. The source + * requirement maybe belongs to one of parents. + * + * @param requirementImplData + * @param requirementUid + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateReqImplToRequirement( + RequirementImplData requirementImplData, String requirementUid) { + + UniqueIdData to = new UniqueIdData(NodeTypeEnum.Requirement, requirementUid); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement " + + requirementUid); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao + .createRelation(requirementImplData, to, GraphEdgeLabels.IMPLEMENTATION_OF, null); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to requirement " + + requirementUid + ". status is " + createRelResult); + + return createRelResult; + } + + /** + * Associate requirement impl node to the node which supply this + * requirement. + * + * @param requirementImplData + * @param nodeId + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateReqImplToImplResource( + RequirementImplData requirementImplData, String nodeId) { + + UniqueIdData nodeImpl = new UniqueIdData(NodeTypeEnum.Resource, nodeId); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), nodeId); + log.debug("Before creating edge between requirement impl " + requirementImplData + " to node impl " + nodeId); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao + .createRelation(requirementImplData, nodeImpl, GraphEdgeLabels.NODE_IMPL, props); + log.debug("After creating edge between requirement " + requirementImplData + " to node impl " + nodeId + + ". status is " + createRelResult); + + return createRelResult; + } + + /** + * create an edge between the requirement impl node to the implementation + * resource. + * + * @param resourceLabel + * @param resourceId + * @param reqName + * @param requirementImplData + * @return + */ + private Either<GraphRelation, TitanOperationStatus> associateReqImplRoResource(NodeTypeEnum resourceLabel, + String resourceId, String reqName, RequirementImplData requirementImplData) { + + UniqueIdData resource = new UniqueIdData(resourceLabel, resourceId); + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), reqName); + log.debug( + "Before creating edge between resource " + resourceId + " to requirement impl " + requirementImplData); + Either<GraphRelation, TitanOperationStatus> createRelResult = titanGenericDao.createRelation(resource, + requirementImplData, GraphEdgeLabels.REQUIREMENT_IMPL, props); + log.debug("After creating edge between to requirement impl " + requirementImplData + " to resource " + resource + + ". status is " + createRelResult); + + return createRelResult; + } + + private void validateNodeExists(String node) { + // TODO Auto-generated method stub + + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> addRequirementToResource(String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) { + + Either<RequirementDefinition, StorageOperationStatus> result = null; + try { + + log.debug("Going to add requirement " + reqName + " to resource " + resourceId + + ". requirement definition is " + reqDefinition); + + validateNodeExists(reqDefinition.getNode()); + + // 1. add requirement node in graph and associate it to the resource + log.debug("Going to add requirement node in graph and associate it to the resource"); + Either<RequirementData, TitanOperationStatus> addRequirementData = addRequirementData(resourceId, reqName, + reqDefinition); + if (addRequirementData.isRight()) { + log.error("Failed to add requirement " + reqName + " node to graph. status is " + addRequirementData); + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value())); + return result; + } + + RequirementData requirementData = addRequirementData.left().value(); + + log.debug("Going to associate the requirement to the appriopriate capability type"); + Either<GraphRelation, TitanOperationStatus> associateReqToCapabilityType = associateRequirementToCapabilityType( + requirementData, reqDefinition); + if (associateReqToCapabilityType.isRight()) { + log.error("Failed to associate requirement data node " + requirementData + + " to the capability type node " + reqDefinition.getCapability()); + result = Either.right(DaoStatusConverter + .convertTitanStatusToStorageStatus(associateReqToCapabilityType.right().value())); + return result; + } + + // TODO: esofer associate requirement to the relationship type + /* + * Either<GraphRelation, TitanOperationStatus> + * associateReqToRelshipType = + * associateRequirementToRelationshipType( requirementData, + * reqDefinition); + * + * if (associateReqToRelshipType.isRight() && + * associateReqToRelshipType.right().value() != + * TitanOperationStatus.NOT_FOUND) { + * log.error("Failed to associate requirement data node " + + * requirementData + " to the relationship type node " + + * reqDefinition.getRelationship()); result = Either + * .right(TitanStatusConverter + * .convertTitanStatusToStorageStatus(associateReqToRelshipType + * .right().value())); return result; } + */ + + log.debug("Going to fetch the requirement " + reqName + " from graph"); + Either<RequirementDefinition, TitanOperationStatus> requirementDefinitionRes = getRequirement( + requirementData.getUniqueId()); + if (requirementDefinitionRes.isRight()) { + result = Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(requirementDefinitionRes.right().value())); + return result; + } + + result = Either.left(requirementDefinitionRes.left().value()); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public StorageOperationStatus addRequirementToResource(TitanVertex metadataVertex, String reqName, + RequirementDefinition reqDefinition, String resourceId, boolean inTransaction) { + + StorageOperationStatus result = StorageOperationStatus.OK; + try { + + log.debug("Going to add requirement {} to resource . requirement definition is ", reqName, resourceId, + reqDefinition); + + validateNodeExists(reqDefinition.getNode()); + + // 1. add requirement node in graph and associate it to the resource + log.debug("Going to add requirement node in graph and associate it to the resource"); + Either<TitanVertex, TitanOperationStatus> addRequirementData = addRequirementData(metadataVertex, + resourceId, reqName, reqDefinition); + if (addRequirementData.isRight()) { + log.error("Failed to add requirement {} node to graph. status is {}", reqName, + addRequirementData.right().value()); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(addRequirementData.right().value()); + return result; + } + + log.debug("Going to associate the requirement to the appriopriate capability type"); + TitanOperationStatus associateReqToCapabilityType = associateRequirementToCapabilityType( + addRequirementData.left().value(), reqDefinition); + if (!associateReqToCapabilityType.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate requirement data node {} to the capability type node {}" + reqDefinition, + reqDefinition.getCapability()); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(associateReqToCapabilityType); + return result; + } + return result; + + } finally { + if (false == inTransaction) { + if (result == null || !result.equals(TitanOperationStatus.OK)) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + /** + * Fetch requirement from graph + * + * @param uniqueId + * - the uniqueid of the requirement in the graph + * @return + */ + public Either<RequirementDefinition, TitanOperationStatus> getRequirement(String uniqueId) { + + log.debug("Going to fetch the requirement {} from graph.", uniqueId); + Either<RequirementData, TitanOperationStatus> reqDataResult = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), uniqueId, RequirementData.class); + + if (reqDataResult.isRight()) { + log.error("Failed to find requirement node in graph " + uniqueId + ". status is " + reqDataResult); + return Either.right(reqDataResult.right().value()); + } + + log.debug("Going to fetch the capability type associate to requirement {}", uniqueId); + Either<ImmutablePair<CapabilityTypeData, GraphEdge>, TitanOperationStatus> capabilityTypeRes = titanGenericDao + .getChild(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.CAPABILITY_TYPE, + NodeTypeEnum.CapabilityType, CapabilityTypeData.class); + + if (capabilityTypeRes.isRight()) { + log.error("Cannot find the capability of a given requirement " + uniqueId + ". status is " + + capabilityTypeRes); + return Either.right(capabilityTypeRes.right().value()); + } + + ImmutablePair<CapabilityTypeData, GraphEdge> capability = capabilityTypeRes.left().value(); + + String capabilityType = capability.getKey().getCapabilityTypeDataDefinition().getType(); + + // TODO: esofer add relationship as edge + /* + * Either<List<ImmutablePair<RelationshipTypeData, GraphEdge>>, + * TitanOperationStatus> relationshipRes = titanGenericDao + * .getChildrenNodes( GraphPropertiesDictionary.UNIQUE_ID.getProperty(), + * uniqueId, GraphEdgeLabels.RELATIONSHIP_TYPE, + * NodeTypeEnum.RelationshipType, RelationshipTypeData.class); + * + * if (relationshipRes.isRight() && relationshipRes.right().value() != + * TitanOperationStatus.NOT_FOUND) { + * log.error("Cannot find the capability of a given requirement " + + * uniqueId + ". status is " + capabilityTypesRes); return + * Either.right(relationshipRes.right().value()); } + * + * String relationshipType = null; if (relationshipRes.isLeft()) { + * List<ImmutablePair<RelationshipTypeData, GraphEdge>> rstPairs = + * relationshipRes .left().value(); if (rstPairs == null || true == + * rstPairs.isEmpty()) { log.error( + * "Cannot find the capability of a given requirement " + uniqueId); + * return Either.right(TitanOperationStatus.NOT_FOUND); } + * + * ImmutablePair<RelationshipTypeData, GraphEdge> relationship = + * rstPairs .get(0); relationshipType = relationship.getKey().getType(); + * } + */ + + log.debug("Going to fetch the capability type associate to requirement {}", uniqueId); + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao + .getParentNode(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueId, GraphEdgeLabels.REQUIREMENT, + NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentNode.isRight()) { + log.error("Cannot find the parent resource for a given requirement " + uniqueId + ". status is " + + parentNode.right().value()); + return Either.right(parentNode.right().value()); + } + + RequirementData requirementData = reqDataResult.left().value(); + + RequirementDefinition requirementDefinition = new RequirementDefinition(); + requirementDefinition.setOwnerId(parentNode.left().value().getLeft().getMetadataDataDefinition().getUniqueId()); + requirementDefinition.setNode(requirementData.getNode()); + requirementDefinition.setUniqueId(requirementData.getUniqueId()); + requirementDefinition.setCapability(capabilityType); + requirementDefinition.setRelationship(requirementData.getRelationshipType()); + requirementDefinition.setMinOccurrences(requirementData.getMinOccurrences()); + requirementDefinition.setMaxOccurrences(requirementData.getMaxOccurrences()); + + return Either.left(requirementDefinition); + + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName, + String resourceId) { + + return getRequirementOfResource(reqName, resourceId, false); + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> getRequirementOfResource(String reqName, + String resourceId, boolean inTransaction) { + + Either<RequirementDefinition, StorageOperationStatus> result = null; + + try { + String reqUniqueId = UniqueIdBuilder.buildRequirementUid(resourceId, reqName); + Either<RequirementDefinition, TitanOperationStatus> requirementRes = getRequirement(reqUniqueId); + + if (requirementRes.isRight()) { + log.debug("Failed to retrieve requirement " + reqName + " associated to resource " + resourceId); + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(requirementRes.right().value())); + } else { + result = Either.left(requirementRes.left().value()); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName, + RequirementImplDef reqDefinition, String resourceId, String parentReqUniqueId) { + + return addRequirementImplToResource(reqName, reqDefinition, resourceId, parentReqUniqueId, false); + + } + + @Override + public Either<RequirementDefinition, StorageOperationStatus> addRequirementImplToResource(String reqName, + RequirementImplDef reqImplDefinition, String resourceId, String parentReqUniqueId, boolean inTransaction) { + + Either<RequirementDefinition, StorageOperationStatus> result = null; + + try { + + // find the requirement defined at the resource itself or under one + // of its parents + Either<RequirementDefinition, TitanOperationStatus> findReq = getRequirement(parentReqUniqueId); + log.debug("After looking for requirement " + parentReqUniqueId + ". status is " + findReq); + if (findReq.isRight()) { + TitanOperationStatus status = findReq.right().value(); + log.error("The requirment " + parentReqUniqueId + " was not found in the graph. status is " + + findReq.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + RequirementDefinition reqDefinition = findReq.left().value(); + String reqNode = reqDefinition.getNode(); + String reqCapability = reqDefinition.getCapability(); + + String nodeIdImpl = reqImplDefinition.getNodeId(); + + checkNodeIdImplementsRequirementNode(nodeIdImpl, reqNode); + + Either<RequirementImplData, TitanOperationStatus> addRequirementImplData = addRequirementImplData( + NodeTypeEnum.Resource, resourceId, reqName, parentReqUniqueId, reqImplDefinition); + + if (addRequirementImplData.isRight()) { + TitanOperationStatus status = addRequirementImplData.right().value(); + log.error("Failed to add requirement data impl node in the graph. status is " + + addRequirementImplData.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + RequirementImplData requirementImplData = addRequirementImplData.left().value(); + + log.debug("Add the properties of the capabilities of the target node " + nodeIdImpl + + " to the requirement impl node " + requirementImplData.getUniqueId() + " in graph."); + Map<String, CapabiltyInstance> requirementPropertiesPerCapability = reqImplDefinition + .getRequirementProperties(); + TitanOperationStatus addPropsResult = addCapabilityPropertiesToReqImpl(requirementImplData, reqCapability, + nodeIdImpl, requirementPropertiesPerCapability); + + if (addPropsResult != TitanOperationStatus.OK) { + log.error("Failed to add capabilities properties to Requirement impl " + requirementImplData); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(addPropsResult)); + return result; + } + + result = Either.left(reqDefinition); + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + return result; + } + + private Either<RequirementImplDef, TitanOperationStatus> getRequirementImplOfResource(String reqName, + String resourceId) { + + RequirementImplDef requirementImplDef = new RequirementImplDef(); + + Either<List<ImmutablePair<RequirementImplData, GraphEdge>>, TitanOperationStatus> reqImplNodesRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.REQUIREMENT_IMPL, NodeTypeEnum.RequirementImpl, RequirementImplData.class); + log.debug("After looking for requirement impl edge of resource " + resourceId); + if (reqImplNodesRes.isRight()) { + TitanOperationStatus status = reqImplNodesRes.right().value(); + return Either.right(status); + } + + boolean found = false; + List<ImmutablePair<RequirementImplData, GraphEdge>> reqImplNodes = reqImplNodesRes.left().value(); + for (ImmutablePair<RequirementImplData, GraphEdge> entry : reqImplNodes) { + GraphEdge graphEdge = entry.getValue(); + String edgeType = (String) graphEdge.getProperties().get(GraphPropertiesDictionary.NAME.getProperty()); + if (reqName.equals(edgeType)) { + found = true; + RequirementImplData requirementImplData = entry.getKey(); + + requirementImplDef.setUniqueId(requirementImplData.getUniqueId()); + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> nodeImplRes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl), + requirementImplData.getUniqueId(), GraphEdgeLabels.NODE_IMPL, NodeTypeEnum.Resource, + ResourceMetadataData.class); + + if (nodeImplRes.isRight()) { + TitanOperationStatus status = nodeImplRes.right().value(); + log.debug("No implementation resource was found under requirement impl " + + requirementImplData.getUniqueId() + ". status is " + status); + + return Either.right(status); + } + String nodeImpl = nodeImplRes.left().value().getKey().getMetadataDataDefinition().getUniqueId(); + requirementImplDef.setNodeId(nodeImpl); + + String posX = requirementImplData.getPosX(); + String posY = requirementImplData.getPosY(); + if (posX != null && posY != null) { + Point point = new Point(posX, posY); + requirementImplDef.setPoint(point); + } + + Either<List<ImmutablePair<CapabilityInstData, GraphEdge>>, TitanOperationStatus> capaInstDataRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RequirementImpl), + requirementImplData.getUniqueId(), GraphEdgeLabels.CAPABILITY_INST, + NodeTypeEnum.CapabilityInst, CapabilityInstData.class); + if (capaInstDataRes.isRight()) { + TitanOperationStatus status = capaInstDataRes.right().value(); + log.debug("No capability instance was found under requirement impl " + + requirementImplData.getUniqueId() + ". status is " + status); + + return Either.right(status); + } + + Map<String, CapabiltyInstance> requirementProperties = new HashMap<String, CapabiltyInstance>(); + + List<ImmutablePair<CapabilityInstData, GraphEdge>> list = capaInstDataRes.left().value(); + for (ImmutablePair<CapabilityInstData, GraphEdge> capabilityInst : list) { + CapabilityInstData capabilityInstData = capabilityInst.getKey(); + GraphEdge edge = capabilityInst.getValue(); + Map<String, Object> properties = edge.getProperties(); + if (properties == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + edge); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + String capabilityName = (String) properties.get(GraphPropertiesDictionary.NAME.getProperty()); + if (capabilityName == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + edge); + return Either.right(TitanOperationStatus.INVALID_ELEMENT); + } + + // List<String> keyValuePropertiesList = capabilityInstData + // .getProperties(); + // Map<String, String> actualValues = new HashMap<String, + // String>(); + // fillMapFromKeyValueList(keyValuePropertiesList, + // actualValues); + CapabiltyInstance capabiltyInstance = new CapabiltyInstance(); + capabiltyInstance.setUniqueId(capabilityInstData.getUniqueId()); + // capabiltyInstance.setProperties(actualValues); + requirementProperties.put(capabilityName, capabiltyInstance); + + Either<List<ImmutablePair<PropertyValueData, GraphEdge>>, TitanOperationStatus> propertyValueNodesRes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.CapabilityInst), + capabilityInstData.getUniqueId(), GraphEdgeLabels.PROPERTY_VALUE, + NodeTypeEnum.PropertyValue, PropertyValueData.class); + + if (propertyValueNodesRes.isRight()) { + TitanOperationStatus status = propertyValueNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find the property values of capability instance " + capabilityInstData + + ". status is " + status); + return Either.right(status); + } + } else { + List<ImmutablePair<PropertyValueData, GraphEdge>> propertyValueNodes = propertyValueNodesRes + .left().value(); + + if (propertyValueNodes != null) { + + Map<String, String> actualValues = new HashMap<String, String>(); + TitanOperationStatus fillPropertiesResult = fillPropertiesMapFromNodes(propertyValueNodes, + actualValues); + + if (fillPropertiesResult != TitanOperationStatus.OK) { + log.error("Failed to fetch properties of capability " + capabilityName); + return Either.right(fillPropertiesResult); + } + + if (false == actualValues.isEmpty()) { + capabiltyInstance.setProperties(actualValues); + } + } + } + + } + + requirementImplDef.setRequirementProperties(requirementProperties); + + break; + } else { + continue; + } + } + + if (false == found) { + log.debug("Cannot find requirement impl under resource " + resourceId); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + return Either.left(requirementImplDef); + } + + private void fillMapFromKeyValueList(List<String> keyValuePropertiesList, Map<String, String> actualValues) { + + if (keyValuePropertiesList != null) { + for (String keyValue : keyValuePropertiesList) { + int equalSignLocation = keyValue.indexOf(EQUAL_SIGN); + if (equalSignLocation > -1) { + String key = keyValue.substring(0, equalSignLocation); + String value = EMPTY_STRING; + if (equalSignLocation + 1 < keyValue.length()) { + value = keyValue.substring(equalSignLocation + 1); + } + actualValues.put(key, value); + } + } + } + + } + + private TitanOperationStatus fillPropertiesMapFromNodes( + List<ImmutablePair<PropertyValueData, GraphEdge>> propertyValueNodes, Map<String, String> actualValues) { + if (propertyValueNodes != null) { + for (ImmutablePair<PropertyValueData, GraphEdge> propertyValuePair : propertyValueNodes) { + PropertyValueData propertyValueData = propertyValuePair.getKey(); + GraphEdge propertyValueEdge = propertyValuePair.getValue(); + Map<String, Object> propertyEdgeProps = propertyValueEdge.getProperties(); + if (propertyEdgeProps == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + propertyValueEdge); + return TitanOperationStatus.INVALID_ELEMENT; + } + String paramName = (String) propertyEdgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (paramName == null) { + log.error("Cannot find the property " + GraphPropertiesDictionary.NAME.getProperty() + + " on the edge " + propertyValueEdge); + return TitanOperationStatus.INVALID_ELEMENT; + } + actualValues.put(paramName, propertyValueData.getValue()); + } + } + return TitanOperationStatus.OK; + } + + private TitanOperationStatus addCapabilityPropertiesToReqImpl(RequirementImplData reqImplData, String reqCapability, + String nodeIdImpl, Map<String, CapabiltyInstance> propertiesValuePerCapability) { + + TitanOperationStatus result = null; + + Either<List<ImmutablePair<CapabilityData, GraphEdge>>, TitanOperationStatus> allCapabilities = capabilityOperation + .getAllCapabilitiesPairs(nodeIdImpl); + log.trace("Atter looking for the capabilities of resource " + nodeIdImpl + ". result is " + allCapabilities); + if (allCapabilities.isRight()) { + TitanOperationStatus status = allCapabilities.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to find capabilities of resource " + nodeIdImpl + ". status is " + status); + return status; + } + } else { + + List<ImmutablePair<CapabilityData, GraphEdge>> capabilitiesValue = allCapabilities.left().value(); + checkImplNodeContainsReqCapability(reqCapability, capabilitiesValue); + + for (ImmutablePair<CapabilityData, GraphEdge> entry : capabilitiesValue) { + + CapabilityData capabilityData = entry.getKey(); + + GraphEdge graphEdge = entry.getValue(); + + Either<String, TitanOperationStatus> capabilityNameResult = findCapabilityName(capabilityData, + graphEdge); + + if (capabilityNameResult.isRight()) { + TitanOperationStatus status = capabilityNameResult.right().value(); + log.error( + "Failed to find capability name from the edge associated to capability " + capabilityData); + return status; + } + + String capabilityName = capabilityNameResult.left().value(); + log.debug("Going to set properties of capability " + capabilityName); + String cabilityDataUid = capabilityData.getUniqueId(); + + Either<CapabilityTypeData, TitanOperationStatus> ctDataResult = capabilityOperation + .getCapabilityTypeOfCapability(cabilityDataUid); + + if (ctDataResult.isRight()) { + log.error("Cannot find capability type of capbility " + cabilityDataUid + ". status is " + + ctDataResult); + TitanOperationStatus status = ctDataResult.right().value(); + return status; + } + + CapabilityTypeData capabilityTypeData = ctDataResult.left().value(); + + Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesStatus = findPropertiesOfCapability( + capabilityTypeData); + if (propertiesStatus.isRight()) { + TitanOperationStatus status = propertiesStatus.right().value(); + log.error("Failed to fetch properties definitions from capability. status is " + status); + return status; + } + + Map<String, PropertyDefinition> properties = propertiesStatus.left().value(); + + CapabiltyInstance capabiltyInstance = null; + if (propertiesValuePerCapability != null) { + capabiltyInstance = propertiesValuePerCapability.get(capabilityName); + } + + Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceNode = createCapabilityInstanceNode( + capabilityName, reqImplData); + if (createCapabilityInstanceNode.isRight()) { + TitanOperationStatus status = createCapabilityInstanceNode.right().value(); + log.error("Failed to create capability instance node (" + capabilityName + ") in graph. status is " + + status); + + return status; + } + CapabilityInstData capabilityInstData = createCapabilityInstanceNode.left().value(); + + Either<List<GraphRelation>, TitanOperationStatus> instanceProperties = addPropertiesToCapabilityInstance( + properties, capabiltyInstance, capabilityInstData); + + if (instanceProperties.isRight()) { + TitanOperationStatus status = instanceProperties.right().value(); + log.debug("Failed to add properties to capability instance. status is " + status); + return status; + } + + Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToCapabilityType = associateCapabilityInstToCapabilityType( + capabilityInstData, capabilityTypeData); + if (associateCapabilityInstToCapabilityType.isRight()) { + TitanOperationStatus status = associateCapabilityInstToCapabilityType.right().value(); + log.error("Failed to associate capability instance " + capabilityInstData + + " to capability type node " + capabilityTypeData + " in graph. status is " + status); + + return status; + } + + Either<GraphRelation, TitanOperationStatus> associateCapabilityInst = associateRequirementImplToCapabilityInst( + reqImplData, capabilityInstData, capabilityName); + if (associateCapabilityInst.isRight()) { + TitanOperationStatus status = associateCapabilityInst.right().value(); + log.error("Failed to associate requirement impl " + reqImplData + " to capability instance node " + + capabilityInstData + " of capability " + capabilityName + ") in graph. status is " + + status); + + return status; + } + + } + result = TitanOperationStatus.OK; + } + return result; + } + + private Either<Map<String, PropertyDefinition>, TitanOperationStatus> findPropertiesOfCapability( + CapabilityTypeData capabilityTypeData) { + String capabilityTypeUid = capabilityTypeData.getUniqueId(); + + Either<CapabilityTypeDefinition, TitanOperationStatus> capabilityTypeResult = capabilityTypeOperation + .getCapabilityTypeByUid(capabilityTypeUid); + + if (capabilityTypeResult.isRight()) { + log.error("Failed to find capabilityType " + capabilityTypeUid + " in the graph. status is " + + capabilityTypeResult); + return Either.right(capabilityTypeResult.right().value()); + } + + CapabilityTypeDefinition capabilityTypeDef = capabilityTypeResult.left().value(); + Map<String, PropertyDefinition> properties = capabilityTypeDef.getProperties(); + + return Either.left(properties); + } + + private Either<String, TitanOperationStatus> findCapabilityName(CapabilityData capabilityData, + GraphEdge graphEdge) { + Map<String, Object> edgeProps = graphEdge.getProperties(); + String capabilityName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + + if (capabilityName == null) { + log.debug("Cannot find the name of the capability associated to node " + capabilityData); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + return Either.left(capabilityName); + } + + private Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToCapabilityType( + CapabilityInstData capabilityInstData, CapabilityTypeData capabilityTypeData) { + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(capabilityInstData, + capabilityTypeData, GraphEdgeLabels.INSTANCE_OF, null); + + return createRelation; + + } + + /** + * add property value node with default value of override value and + * associate it to the capability instance node + * + * @param properties + * - properties definition. old also default value + * @param capabilityInstance + * - hold also properties new value(if exists) + * @param capabilityInstData + * - the graph node which we associate the properties value node + * to. + * @return + */ + private Either<List<GraphRelation>, TitanOperationStatus> addPropertiesToCapabilityInstance( + Map<String, PropertyDefinition> properties, CapabiltyInstance capabilityInstance, + CapabilityInstData capabilityInstData) { + + List<GraphRelation> relationsResult = new ArrayList<GraphRelation>(); + + if (properties != null) { + for (Entry<String, PropertyDefinition> entry : properties.entrySet()) { + + String paramName = entry.getKey(); + + PropertyDefinition propertyDefinition = entry.getValue(); + + String propertyValue = setPropertyValue(capabilityInstance, paramName, propertyDefinition); + + PropertyValueData propertyValueData = buildPropertyValueData(capabilityInstData.getUniqueId(), + paramName, propertyValue); + + log.debug("Before creating property value data node " + propertyValueData + " in graph."); + Either<PropertyValueData, TitanOperationStatus> createNode = titanGenericDao + .createNode(propertyValueData, PropertyValueData.class); + log.debug("Before creating property value data node " + propertyValueData + " in graph. status is " + + createNode); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create property value node in graph " + propertyValueData + ". status is " + + status); + return Either.right(status); + } + + PropertyValueData propertyValueDataCreated = createNode.left().value(); + + Either<GraphRelation, TitanOperationStatus> createRelation = associateCapabilityInstToPropertyValue( + capabilityInstData, paramName, propertyValueDataCreated); + + if (createRelation.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Failed to create relation between capability instance " + + capabilityInstData.getUniqueId() + " to property value " + + propertyValueDataCreated.getUniqueId() + " in graph. status is " + status); + return Either.right(status); + } + + relationsResult.add(createRelation.left().value()); + + } + } + + return Either.left(relationsResult); + } + + private Either<GraphRelation, TitanOperationStatus> associateCapabilityInstToPropertyValue( + CapabilityInstData capabilityInstData, String paramName, PropertyValueData propertyValueDataCreated) { + + Map<String, Object> edgeProps = new HashMap<String, Object>(); + edgeProps.put(GraphPropertiesDictionary.NAME.getProperty(), paramName); + log.debug("Begin creating relation between capability instance " + capabilityInstData + " to property value " + + propertyValueDataCreated + " in graph."); + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(capabilityInstData, + propertyValueDataCreated, GraphEdgeLabels.PROPERTY_VALUE, edgeProps); + log.debug("After creating relation between capability instance " + capabilityInstData + " to property value " + + propertyValueDataCreated + " in graph. status is " + createRelation); + + return createRelation; + } + + private String setPropertyValue(CapabiltyInstance capabilityInstance, String paramName, + PropertyDefinition propertyDefinition) { + String propertyValue = NA; + if (propertyDefinition.getDefaultValue() != null) { + propertyValue = propertyDefinition.getDefaultValue(); + } + Map<String, String> propertiesValue = null; + if (capabilityInstance != null) { + propertiesValue = capabilityInstance.getProperties(); + if (propertiesValue != null) { + String tmpValue = propertiesValue.get(paramName); + if (tmpValue != null) { + propertyValue = tmpValue; + } + } + } + return propertyValue; + } + + private String buildPropertykeyValue(String paramName, String paramValue) { + return paramName + EQUAL_SIGN + paramValue; + } + + private PropertyValueData buildPropertyValueData(String capabilityInstDataUid, String paramName, + String propertyValue) { + PropertyValueData propertyValueData = new PropertyValueData(); + propertyValueData.setValue(propertyValue); + String uid = UniqueIdBuilder.buildPropertyValueUniqueId(capabilityInstDataUid, paramName); + propertyValueData.setUniqueId(uid); + Long creationDate = System.currentTimeMillis(); + propertyValueData.setCreationTime(creationDate); + propertyValueData.setModificationTime(creationDate); + return propertyValueData; + } + + private Either<CapabilityInstData, TitanOperationStatus> createCapabilityInstanceNode(String capabilityName, + RequirementImplData reqImplData) { + + CapabilityInstData capabilityInstData = new CapabilityInstData(); + String uniqueId = UniqueIdBuilder.buildCapabilityInstanceUid(reqImplData.getUniqueId(), capabilityName); + + capabilityInstData.setUniqueId(uniqueId); + // capabilityInstData.setProperties(instanceProperties); + Long creationDate = System.currentTimeMillis(); + capabilityInstData.setCreationTime(creationDate); + capabilityInstData.setModificationTime(creationDate); + + log.debug("Before creating capability instance node in graph " + capabilityInstData); + Either<CapabilityInstData, TitanOperationStatus> createNode = titanGenericDao.createNode(capabilityInstData, + CapabilityInstData.class); + log.debug( + "After creating capability instance node in graph " + capabilityInstData + ". status is " + createNode); + + return createNode; + } + + private void checkNodeIdImplementsRequirementNode(String nodeIdImpl, String reqNode) { + // TODO Auto-generated method stub + + } + + private void checkImplNodeContainsReqCapability(String reqCapability, + List<ImmutablePair<CapabilityData, GraphEdge>> capabilitiesValue) { + // TODO Auto-generated method stub + + } + + public Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> getAllRequirementsOfResourceOnly( + String resourceId, boolean inTransaction) { + + Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> result = null; + + try { + + Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>(); + Set<String> caseInsensitiveReqNames = new HashSet<>(); + TitanOperationStatus status = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + + if (status != TitanOperationStatus.OK) { + log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } else { + // TODO handle requirementImpl + result = Either.left(convertRequirementMap(requirements, null, null)); + } + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + @Override + public Either<Map<String, RequirementDefinition>, TitanOperationStatus> getResourceRequirements(String resourceId) { + + Either<Map<String, RequirementDefinition>, TitanOperationStatus> result = null; + + Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>(); + Set<String> caseInsensitiveReqNames = new HashSet<>(); + + TitanOperationStatus status = findAllRequirementsRecursively(resourceId, requirements, caseInsensitiveReqNames); + if (status != TitanOperationStatus.OK) { + log.error("Failed to get all requirements of resource " + resourceId + ". status is " + status); + return Either.right(status); + } else { + log.debug("The requirements returned for resource {} are {}", resourceId, requirements); + + if (requirements != null) { + for (Entry<String, RequirementDefinition> entry : requirements.entrySet()) { + String reqName = entry.getKey(); + Either<RequirementImplDef, TitanOperationStatus> reqImplRes = this + .getRequirementImplOfResource(reqName, resourceId); + if (reqImplRes.isRight()) { + + TitanOperationStatus reqImplResStatus = reqImplRes.right().value(); + if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Cannot find implementation of requirement {} under resource {}", reqName, + resourceId); + } else { + log.error("Cannot find implementation of requirement {} under resource {}", reqName, + resourceId); + return Either.right(reqImplResStatus); + } + } else { + RequirementDefinition requirementDefinition = entry.getValue(); + // RequirementImplDef requirementImplDef = + // reqImplRes.left().value(); + // requirementDefinition.setRequirementImpl(requirementImplDef); + } + } + } + log.debug("The requirements returned for resource {} after fetching requirement impl are {}", resourceId, + requirements); + + result = Either.left(requirements); + + return result; + } + + } + + @Override + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> getAllResourceRequirements( + String resourceId, boolean inTransaction) { + + Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = null; + + try { + + Either<Map<String, RequirementDefinition>, TitanOperationStatus> internalResult = getResourceRequirements( + resourceId); + if (internalResult.isRight()) { + TitanOperationStatus status = internalResult.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to fetch requirements of resource {} . status is {}", resourceId, status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map<String, RequirementDefinition> value = internalResult.left().value(); + + result = Either.left(value); + return result; + + // Map<String, RequirementDefinition> requirements = new + // HashMap<String, RequirementDefinition>(); + // TitanOperationStatus status = findAllRequirementsRecursively( + // resourceId, requirements); + // if (status != TitanOperationStatus.OK) { + // log.error("Failed to get all requirements of resource " + // + resourceId + ". status is " + status); + // return Either.right(TitanStatusConverter + // .convertTitanStatusToStorageStatus(status)); + // } else { + // log.debug("The requirements returned for resource " + // + resourceId + " are " + requirements); + // + // if (requirements != null) { + // for (Entry<String, RequirementDefinition> entry : requirements + // .entrySet()) { + // String reqName = entry.getKey(); + // Either<RequirementImplDef, TitanOperationStatus> reqImplRes = + // this + // .getRequirementImplOfResource(reqName, + // resourceId); + // if (reqImplRes.isRight()) { + // + // TitanOperationStatus reqImplResStatus = reqImplRes + // .right().value(); + // if (reqImplResStatus == TitanOperationStatus.NOT_FOUND) { + // log.warn("Cannot find implementation of requirement " + // + reqName + // + " under resource " + // + resourceId); + // } else { + // log.error("Cannot find implementation of requirement " + // + reqName + // + " under resource " + // + resourceId); + // return Either + // .right(TitanStatusConverter + // .convertTitanStatusToStorageStatus(reqImplResStatus)); + // } + // } else { + // RequirementDefinition requirementDefinition = entry + // .getValue(); + // RequirementImplDef requirementImplDef = reqImplRes + // .left().value(); + // requirementDefinition + // .setRequirementImpl(requirementImplDef); + // } + // } + // } + // log.debug("The requirements returned for resource " + // + resourceId + " after fetching requirement impl are " + // + requirements); + // + // result = Either.left(requirements); + // + // return result; + // } + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> getAllResourceRequirements( + String resourceId) { + + return getAllResourceRequirements(resourceId, false); + + } + + public TitanOperationStatus findAllRequirementsRecursively(String resourceId, + Map<String, RequirementDefinition> requirements, Set<String> caseInsensitiveReqNames) { + + TitanOperationStatus nonRecursiveResult = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + if (!nonRecursiveResult.equals(TitanOperationStatus.OK) + && !nonRecursiveResult.equals(TitanOperationStatus.NOT_FOUND)) { + return nonRecursiveResult; + } + + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentNodes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + + if (parentNodes.isRight()) { + TitanOperationStatus parentNodesStatus = parentNodes.right().value(); + if (parentNodesStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Finish to lookup for parnet requirements"); + return TitanOperationStatus.OK; + } else { + log.error("Failed to find parent requirements of resource {} . status is {}", resourceId, + parentNodesStatus); + return parentNodesStatus; + } + } + ImmutablePair<ResourceMetadataData, GraphEdge> parnetNodePair = parentNodes.left().value(); + String parentUniqueId = parnetNodePair.getKey().getMetadataDataDefinition().getUniqueId(); + TitanOperationStatus addParentReqStatus = findAllRequirementsRecursively(parentUniqueId, requirements, + caseInsensitiveReqNames); + + if (addParentReqStatus != TitanOperationStatus.OK) { + log.error("Failed to fetch all requirements of resource {}", parentUniqueId); + return addParentReqStatus; + } + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus findAllRequirementsNonRecursive(String resourceId, + Map<String, RequirementDefinition> requirements, Set<String> caseInsensitiveReqNames) { + Either<List<ImmutablePair<RequirementData, GraphEdge>>, TitanOperationStatus> requirementNodes = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, + GraphEdgeLabels.REQUIREMENT, NodeTypeEnum.Requirement, RequirementData.class); + + if (requirementNodes.isRight()) { + TitanOperationStatus status = requirementNodes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return status; + } + } else { + List<ImmutablePair<RequirementData, GraphEdge>> requirementList = requirementNodes.left().value(); + if (requirementList != null) { + for (ImmutablePair<RequirementData, GraphEdge> requirementPair : requirementList) { + String reqUniqueId = requirementPair.getKey().getUniqueId(); + Map<String, Object> edgeProps = requirementPair.getValue().getProperties(); + String reqName = null; + if (edgeProps != null) { + reqName = (String) edgeProps.get(GraphPropertiesDictionary.NAME.getProperty()); + if (reqName == null) { + log.error("The requirement name is missing on the edge of requirement " + reqUniqueId); + return TitanOperationStatus.INVALID_ELEMENT; + } + } else { + log.error("The requirement name is missing on the edge of requirement " + reqUniqueId); + return TitanOperationStatus.INVALID_ELEMENT; + } + Either<RequirementDefinition, TitanOperationStatus> requirementDefRes = this + .getRequirement(reqUniqueId); + if (requirementDefRes.isRight()) { + TitanOperationStatus status = requirementDefRes.right().value(); + log.error("Failed to get requirement properties of requirement " + reqUniqueId); + return status; + } + + RequirementDefinition requirementDefinition = requirementDefRes.left().value(); + requirementDefinition.setName(reqName); + // US631462 + if (caseInsensitiveReqNames.contains(reqName.toLowerCase())) { + log.debug( + "The requirement {} was already defined in derived resource (case insensitive). Ignore {} from resource {}", + reqName, reqName, resourceId); + } else { + requirements.put(reqName, requirementDefinition); + caseInsensitiveReqNames.add(reqName.toLowerCase()); + } + + } + } + } + return TitanOperationStatus.OK; + } + + public StorageOperationStatus deleteRequirementFromGraph(String requirementId) { + log.debug("Before deleting requirement from graph " + requirementId); + Either<RequirementData, TitanOperationStatus> deleteNodeStatus = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementId, RequirementData.class); + if (deleteNodeStatus.isRight()) { + log.error("failed to delete requirement with id {}. status={}", requirementId, + deleteNodeStatus.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(deleteNodeStatus.right().value()); + } + return StorageOperationStatus.OK; + } + + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRequirements(String resourceId) { + + return getAllResourceRequirements(resourceId, false); + + } + + public Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRequirements(String resourceId, + boolean inTransaction) { + + Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = null; + + try { + Either<Map<String, RequirementDefinition>, TitanOperationStatus> deleteAllRes = deleteAllRequirementsOfResource( + resourceId); + if (deleteAllRes.isRight()) { + TitanOperationStatus status = deleteAllRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to delete requirements of resource " + resourceId + ". status is " + status); + } + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + Map<String, RequirementDefinition> value = deleteAllRes.left().value(); + result = Either.left(value); + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + public Either<Map<String, RequirementDefinition>, TitanOperationStatus> deleteAllRequirementsOfResource( + String resourceId) { + + Map<String, RequirementDefinition> requirements = new HashMap<String, RequirementDefinition>(); + Set<String> caseInsensitiveReqNames = new HashSet<>(); + TitanOperationStatus requirementsRes = findAllRequirementsNonRecursive(resourceId, requirements, + caseInsensitiveReqNames); + if (requirementsRes != TitanOperationStatus.OK) { + return Either.right(requirementsRes); + } + + if (requirements.isEmpty()) { + return Either.right(TitanOperationStatus.NOT_FOUND); + } + + for (Entry<String, RequirementDefinition> entry : requirements.entrySet()) { + RequirementDefinition requirementDefinition = entry.getValue(); + + String requirementUid = requirementDefinition.getUniqueId(); + + Either<RequirementData, TitanOperationStatus> deleteNodeRes = titanGenericDao.deleteNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirementUid, RequirementData.class); + if (deleteNodeRes.isRight()) { + TitanOperationStatus status = deleteNodeRes.right().value(); + log.error("Failed to delete requirement " + requirementUid + " of resource " + resourceId); + return Either.right(status); + } + } + + return Either.left(requirements); + + } + + public Map<String, List<RequirementDefinition>> convertRequirementMap( + Map<String, RequirementDefinition> requirementMap, String ownerId, String ownerName) { + + Map<String, List<RequirementDefinition>> typeToRequirementMap = new HashMap<String, List<RequirementDefinition>>(); + requirementMap.forEach((reqName, requirement) -> { + // requirement.setOwnerId(ownerId); + // requirement.setOwnerName(ownerName); + if (typeToRequirementMap.containsKey(requirement.getCapability())) { + typeToRequirementMap.get(requirement.getCapability()).add(requirement); + } else { + List<RequirementDefinition> list = new ArrayList<RequirementDefinition>(); + list.add(requirement); + typeToRequirementMap.put(requirement.getCapability(), list); + } + }); + return typeToRequirementMap; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java new file mode 100644 index 0000000000..22c693d8b3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java @@ -0,0 +1,3089 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.UUID; +import java.util.function.Predicate; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphNode; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.ResourceMetadataDefinition; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.utils.GraphDeleteUtil; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.UniqueIdData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@org.springframework.stereotype.Component("resource-operation") +public class ResourceOperation extends ComponentOperation implements IResourceOperation { + + public ResourceOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(ResourceOperation.class.getName()); + + @javax.annotation.Resource + private PropertyOperation propertyOperation; + + @javax.annotation.Resource + private IAttributeOperation attributeOperation; + + @javax.annotation.Resource + private RequirementOperation requirementOperation; + + @javax.annotation.Resource + private CapabilityOperation capabilityOperation; + + @javax.annotation.Resource + private InterfaceLifecycleOperation interfaceLifecycleOperation; + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private IAdditionalInformationOperation addioAdditionalInformationOperation; + + @javax.annotation.Resource + private GroupOperation groupOperation; + + @javax.annotation.Resource + private ComponentCache componentCache; + + private Gson prettyJson = new GsonBuilder().setPrettyPrinting().create(); + + private GraphDeleteUtil graphDeleteUtil = new GraphDeleteUtil(); + + private static Pattern uuidNewVersion = Pattern.compile("^\\d{1,}.1"); + private static Pattern uuidNormativeNewVersion = Pattern.compile("^\\d{1,}.0"); + + @Override + public Either<Resource, StorageOperationStatus> createResource(Resource resource) { + return createResource(resource, false); + } + + @Override + public Either<Resource, StorageOperationStatus> createResource(Resource resource, boolean inTransaction) { + + Either<Resource, StorageOperationStatus> result = null; + + try { + generateUUID(resource); + + ResourceMetadataData resourceData = getResourceMetaDataFromResource(resource); + String resourceUniqueId = resource.getUniqueId(); + if (resourceUniqueId == null) { + resourceUniqueId = UniqueIdBuilder.buildResourceUniqueId(); + resourceData.getMetadataDataDefinition().setUniqueId(resourceUniqueId); + } + resourceData.getMetadataDataDefinition().setHighestVersion(true); + + String userId = resource.getCreatorUserId(); + + Either<TitanVertex, TitanOperationStatus> findUser = findUserVertex(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + TitanVertex creatorVertex = findUser.left().value(); + TitanVertex updaterVertex = creatorVertex; + + String updaterUserId = resource.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUserVertex(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterVertex = findUser.left().value(); + } + } + + // get derived from resources + List<ResourceMetadataData> derivedResources = null; + Either<List<ResourceMetadataData>, StorageOperationStatus> derivedResourcesResult = findDerivedResources(resource); + if (derivedResourcesResult.isRight()) { + result = Either.right(derivedResourcesResult.right().value()); + return result; + } else { + derivedResources = derivedResourcesResult.left().value(); + } + + List<String> tags = resource.getTags(); + if (tags != null && false == tags.isEmpty()) { + Either<List<TagData>, StorageOperationStatus> tagsResult = createNewTagsList(tags); + if (tagsResult.isRight()) { + result = Either.right(tagsResult.right().value()); + return result; + } + List<TagData> tagsToCreate = tagsResult.left().value(); + StorageOperationStatus status = createTagNodesOnGraph(tagsToCreate); + if (!status.equals(StorageOperationStatus.OK)) { + result = Either.right(status); + return result; + } + } + + Either<TitanVertex, TitanOperationStatus> createdVertex = titanGenericDao.createNode(resourceData); + if (createdVertex.isRight()) { + TitanOperationStatus status = createdVertex.right().value(); + log.error("Error returned after creating resource data node {}. status returned is ", resourceData, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + TitanVertex metadataVertex = createdVertex.left().value(); + + TitanOperationStatus associateMetadata = associateMetadataToResource(resourceData, creatorVertex, updaterVertex, derivedResources, metadataVertex); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + StorageOperationStatus associateCategory = assosiateMetadataToCategory(resource, resourceData); + if (associateCategory != StorageOperationStatus.OK) { + result = Either.right(associateCategory); + return result; + } + + TitanOperationStatus associateProperties = associatePropertiesToResource(metadataVertex, resourceUniqueId, resource.getProperties()); + if (associateProperties != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateProperties)); + return result; + } + + TitanOperationStatus associateAttributes = associateAttributesToResource(metadataVertex, resource.getAttributes(), resourceUniqueId); + if (associateAttributes != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateAttributes)); + return result; + } + + TitanOperationStatus associateInputs = associateInputsToComponent(metadataVertex, resourceUniqueId, resource.getInputs()); + if (associateInputs != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateInputs)); + return result; + } + + StorageOperationStatus associateRequirements = associateRequirementsToResource(metadataVertex, resourceUniqueId, resource.getRequirements()); + if (associateRequirements != StorageOperationStatus.OK) { + result = Either.right(associateRequirements); + return result; + } + + StorageOperationStatus associateCapabilities = associateCapabilitiesToResource(metadataVertex, resourceUniqueId, resource.getCapabilities()); + if (associateCapabilities != StorageOperationStatus.OK) { + result = Either.right(associateCapabilities); + return result; + } + + StorageOperationStatus associateInterfaces = associateInterfacesToResource(resourceData, resource.getInterfaces(), metadataVertex); + if (associateInterfaces != StorageOperationStatus.OK) { + result = Either.right(associateInterfaces); + return result; + } + + Map<String, ArtifactDefinition> resourceArtifacts = resource.getArtifacts(); + Map<String, ArtifactDefinition> deploymentArtifacts = resource.getDeploymentArtifacts(); + Map<String, ArtifactDefinition> toscaArtifacts = resource.getToscaArtifacts(); + if (resourceArtifacts != null) { + if (deploymentArtifacts != null) { + resourceArtifacts.putAll(deploymentArtifacts); + } + } else { + resourceArtifacts = deploymentArtifacts; + } + if (toscaArtifacts != null) { + if (resourceArtifacts != null) { + resourceArtifacts.putAll(toscaArtifacts); + } else { + resourceArtifacts = toscaArtifacts; + } + } + + StorageOperationStatus associateArtifacts = associateArtifactsToResource(metadataVertex, resourceUniqueId, resourceArtifacts); + if (associateArtifacts != StorageOperationStatus.OK) { + result = Either.right(associateArtifacts); + return result; + } + + List<AdditionalInformationDefinition> additionalInformation = resource.getAdditionalInformation(); + StorageOperationStatus addAdditionalInformation = addAdditionalInformationToResource(metadataVertex, resourceUniqueId, additionalInformation); + if (addAdditionalInformation != StorageOperationStatus.OK) { + result = Either.right(addAdditionalInformation); + return result; + } + + result = this.getResource(resourceUniqueId, true); + if (result.isRight()) { + log.error("Cannot get full resource from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Resource retrieved is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus assosiateMetadataToCategory(Resource resource, ResourceMetadataData resourceData) { + // get category + String categoryName = resource.getCategories().get(0).getName(); + String subcategoryName = resource.getCategories().get(0).getSubcategories().get(0).getName(); + + CategoryData categoryData = null; + Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + log.error("Cannot find category " + categoryName + " in the graph. status is " + status); + return categoryResult.right().value(); + } + categoryData = categoryResult.left().value(); + if (categoryData != null) { + Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (childrenNodes.isRight()) { + log.debug("Faield to fetch sub categories for resource category" + categoryData.getCategoryDataDefinition().getName()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value()); + } + for (ImmutablePair<SubCategoryData, GraphEdge> pair : childrenNodes.left().value()) { + SubCategoryData subcategoryData = pair.left; + if (subcategoryData.getSubCategoryDataDefinition().getName().equals(subcategoryName)) { + Either<GraphRelation, TitanOperationStatus> result = titanGenericDao.createRelation(resourceData, subcategoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating resource " + resourceData.getUniqueId() + " to subcategory " + subcategoryData + ". Edge type is " + GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate resource " + resourceData.getUniqueId() + " to category " + categoryData + ". Edge type is " + GraphEdgeLabels.CATEGORY); + return DaoStatusConverter.convertTitanStatusToStorageStatus(result.right().value()); + } + + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus addAdditionalInformationToResource(TitanVertex metadataVertex, String resourceUniqueId, List<AdditionalInformationDefinition> additionalInformation) { + + StorageOperationStatus result = null; + if (additionalInformation == null || true == additionalInformation.isEmpty()) { + result = super.addAdditionalInformation(NodeTypeEnum.Resource, resourceUniqueId, null, metadataVertex); + } else { + if (additionalInformation.size() == 1) { + result = super.addAdditionalInformation(NodeTypeEnum.Resource, resourceUniqueId, additionalInformation.get(0)); + } else { + result = StorageOperationStatus.BAD_REQUEST; + log.info("Cannot create resource with more than one additional information object. The number of received object is {}", additionalInformation.size()); + } + } + return result; + } + + private void generateUUID(Resource resource) { + String prevUUID = resource.getUUID(); + String version = resource.getVersion(); + if ((prevUUID == null && uuidNormativeNewVersion.matcher(version).matches()) || uuidNewVersion.matcher(version).matches()) { + UUID uuid = UUID.randomUUID(); + resource.setUUID(uuid.toString()); + MDC.put("serviceInstanceID", uuid.toString()); + } + } + + @Override + public Either<Resource, StorageOperationStatus> overrideResource(Resource resource, Resource resourceSaved, boolean inTransaction) { + Either<Resource, StorageOperationStatus> result = null; + try { + String resourceId = resourceSaved.getUniqueId(); + + // override interfaces to copy only resource's interfaces and not + // derived interfaces + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfacesOfResourceOnly = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceSaved.getUniqueId(), false, true); + if (interfacesOfResourceOnly.isRight()) { + log.error("failed to get interfaces of resource. resourceId {} status is {}", resourceId, interfacesOfResourceOnly.right().value()); + result = Either.right(interfacesOfResourceOnly.right().value()); + return result; + } + resource.setInterfaces(interfacesOfResourceOnly.left().value()); + resource.setArtifacts(resourceSaved.getArtifacts()); + resource.setDeploymentArtifacts(resourceSaved.getDeploymentArtifacts()); + resource.setGroups(resourceSaved.getGroups()); + resource.setInputs(null); + resource.setLastUpdateDate(null); + resource.setHighestVersion(true); + + // delete former resource + Either<Resource, StorageOperationStatus> deleteResource = deleteResource(resourceId, true); + if (deleteResource.isRight()) { + log.error("failed to delete old resource with id {}. status = {}", resourceId, deleteResource.right().value()); + result = deleteResource; + return result; + } + + Either<Resource, StorageOperationStatus> createResource = createResource(resource, true); + if (createResource.isRight()) { + log.error("failed to create new version of resource {} status = {}", resourceId, createResource.right().value()); + result = createResource; + return result; + } + Resource newResource = createResource.left().value(); + + Either<List<GroupDefinition>, StorageOperationStatus> cloneGroupEither = cloneGroups(resource, newResource, null, inTransaction); + if (cloneGroupEither.isLeft()) { + newResource.setGroups(cloneGroupEither.left().value()); + } else if (cloneGroupEither.right().value() != StorageOperationStatus.OK) { + log.error("failed to clone group of resource {} status = {}", resourceId, cloneGroupEither.right().value()); + result = Either.right(cloneGroupEither.right().value()); + return result; + } + + result = Either.left(newResource); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private StorageOperationStatus associateCapabilitiesToResource(TitanVertex metadataVertex, String resourceIda, Map<String, List<CapabilityDefinition>> capabilities) { + StorageOperationStatus addCapabilityToResource = null; + if (capabilities != null) { + for (Entry<String, List<CapabilityDefinition>> entry : capabilities.entrySet()) { + + List<CapabilityDefinition> capDefinition = entry.getValue(); + for (CapabilityDefinition item : capDefinition) { + addCapabilityToResource = capabilityOperation.addCapability(metadataVertex, resourceIda, item.getName(), item, true); + if (!addCapabilityToResource.equals(StorageOperationStatus.OK)) { + return addCapabilityToResource; + } + + } + } + + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus associateRequirementsToResource(TitanVertex metadataVertex, String resourceId, Map<String, List<RequirementDefinition>> requirements) { + + if (requirements != null) { + for (Entry<String, List<RequirementDefinition>> entry : requirements.entrySet()) { + + List<RequirementDefinition> reqDefinition = entry.getValue(); + for (RequirementDefinition item : reqDefinition) { + StorageOperationStatus addRequirementToResource = requirementOperation.addRequirementToResource(metadataVertex, item.getName(), item, resourceId, true); + + if (!addRequirementToResource.equals(StorageOperationStatus.OK)) { + return addRequirementToResource; + } + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus associateArtifactsToResource(TitanVertex metadataVertex, String resourceId, Map<String, ArtifactDefinition> artifacts) { + + StorageOperationStatus status = StorageOperationStatus.OK; + if (artifacts != null) { + for (Entry<String, ArtifactDefinition> entry : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + status = artifactOperation.addArifactToComponent(artifactDefinition, resourceId, NodeTypeEnum.Resource, false, metadataVertex); + + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + } + return status; + + } + + private StorageOperationStatus associateInterfacesToResource(ResourceMetadataData resourceData, Map<String, InterfaceDefinition> interfaces, TitanVertex metadataVertex) { + + if (interfaces != null) { + for (Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { + + InterfaceDefinition interfaceDefinition = entry.getValue(); + StorageOperationStatus status; + if (((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()).isAbstract()) { + status = interfaceLifecycleOperation.associateInterfaceToNode(resourceData, interfaceDefinition, metadataVertex); + } else { + status = interfaceLifecycleOperation.createInterfaceOnResource(interfaceDefinition, resourceData.getMetadataDataDefinition().getUniqueId(), interfaceDefinition.getType(), false, true, metadataVertex); + } + + if (!status.equals(StorageOperationStatus.OK)) { + return status; + } + } + } + return StorageOperationStatus.OK; + + } + + private Either<Resource, StorageOperationStatus> sendError(TitanOperationStatus status, StorageOperationStatus statusIfNotFound) { + Either<Resource, StorageOperationStatus> result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + private TitanOperationStatus associatePropertiesToResource(TitanVertex metadatVertex, String resourceId, List<PropertyDefinition> properties) { + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + Map<String, PropertyDefinition> convertedProperties = new HashMap<>(); + + if (properties != null) { + for (PropertyDefinition propertyDefinition : properties) { + convertedProperties.put(propertyDefinition.getName(), propertyDefinition); + } + TitanOperationStatus operationStatus = propertyOperation.addPropertiesToGraph(metadatVertex, convertedProperties, allDataTypes.left().value(), resourceId); + return operationStatus; + } + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus associateAttributesToResource(TitanVertex metadataVertex, List<AttributeDefinition> attributes, String resourceId) { + TitanOperationStatus operationStatus = TitanOperationStatus.OK; + + Either<Map<String, DataTypeDefinition>, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus status = allDataTypes.right().value(); + log.debug("Cannot find any data type. Status is {}.", status); + return status; + } + + if (attributes != null) { + Map<String, AttributeDefinition> convertedAttributes = attributes.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + operationStatus = attributeOperation.addAttributesToGraph(metadataVertex, convertedAttributes, resourceId, allDataTypes.left().value()); + } + return operationStatus; + } + + private TitanOperationStatus associateMetadataToResource(ResourceMetadataData resourceData, TitanVertex creatorVertex, TitanVertex updaterVertex, List<ResourceMetadataData> derivedResources, TitanVertex metadataVertex) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.STATE.getProperty(), resourceData.getMetadataDataDefinition().getState()); + + TitanOperationStatus result = titanGenericDao.createEdge(updaterVertex, metadataVertex, GraphEdgeLabels.STATE, props); + log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.STATE); + if (!result.equals(TitanOperationStatus.OK)) { + return result; + } + result = titanGenericDao.createEdge(updaterVertex, metadataVertex, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + if (!result.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate user {} to resource {}. Edge type is {}", updaterVertex, resourceData.getUniqueId(), GraphEdgeLabels.LAST_MODIFIER); + return result; + } + + result = titanGenericDao.createEdge(creatorVertex, metadataVertex, GraphEdgeLabels.CREATOR, null); + log.debug("After associating user {} to resource {}. Edge type is {} ", creatorVertex, resourceData.getUniqueId(), GraphEdgeLabels.CREATOR); + if (!result.equals(TitanOperationStatus.OK)) { + log.error("Failed to associate user {} to resource {}. Edge type is {} ", creatorVertex, resourceData.getUniqueId(), GraphEdgeLabels.CREATOR); + return result; + } + // TODO Evg : need to change too.. + if (derivedResources != null) { + for (ResourceMetadataData derivedResource : derivedResources) { + log.debug("After associating resource " + resourceData.getUniqueId() + " to parent resource " + derivedResource.getUniqueId() + ". Edge type is " + GraphEdgeLabels.DERIVED_FROM); + Either<GraphRelation, TitanOperationStatus> createRelationResult = titanGenericDao.createRelation(resourceData, derivedResource, GraphEdgeLabels.DERIVED_FROM, null); + if (createRelationResult.isRight()) { + log.error("Failed to associate resource {} to derived ", resourceData.getUniqueId()); + return createRelationResult.right().value(); + } + } + } + + return TitanOperationStatus.OK; + } + + public Either<List<ResourceMetadataData>, StorageOperationStatus> findDerivedResources(Resource resource) { + + List<ResourceMetadataData> derivedResources = new ArrayList<ResourceMetadataData>(); + List<String> derivedFromResources = resource.getDerivedFrom(); + if (derivedFromResources != null && false == derivedFromResources.isEmpty()) { + + for (String parentResource : derivedFromResources) { + + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + // propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), + // true); + propertiesToMatch.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), parentResource); + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either<List<ResourceMetadataData>, TitanOperationStatus> getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + List<ResourceMetadataData> resources = null; + if (getParentResources.isRight()) { + /* + * log.debug( "Cannot find parent resource by tosca resource name" + parentResource + " in the graph. Try to find by name"); Map<String, Object> propertiesWithResourceNameToMatch = new HashMap<String, Object>(); + * propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.NAME.getProperty(), parentResource); + * propertiesWithResourceNameToMatch.put( GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty( ), true); + * + * getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesWithResourceNameToMatch, ResourceData.class); if (getParentResources.isRight()) { log.error( + * "Cannot find parent resource by tosca resource name" + parentResource + " in the graph."); return Either.right(StorageOperationStatus. PARENT_RESOURCE_NOT_FOUND); }else{ resources = getParentResources.left().value(); + * + * } + */ + log.error("Cannot find parent resource by tosca resource name" + parentResource + " in the graph."); + return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND); + + } else { + resources = getParentResources.left().value(); + if (resources == null || resources.size() == 0) { + log.error("Cannot find parent resource by tosc name" + parentResource + " in the graph. resources size is empty"); + return Either.right(StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND); + } else { + if (resources.size() > 1) { + log.error("Multiple parent resources called " + parentResource + " found in the graph."); + return Either.right(StorageOperationStatus.MULTIPLE_PARENT_RESOURCE_FOUND); + } + ResourceMetadataData parentResourceData = resources.get(0); + derivedResources.add(parentResourceData); + } + + } + + } + } + return Either.left(derivedResources); + } + + private ResourceMetadataData getResourceMetaDataFromResource(Resource resource) { + ResourceMetadataData resourceData = new ResourceMetadataData((ResourceMetadataDataDefinition) resource.getComponentMetadataDefinition().getMetadataDataDefinition()); + if (resource.getNormalizedName() == null || resource.getNormalizedName().isEmpty()) { + resourceData.getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(resource.getName())); + } + if (resource.getSystemName() == null || resource.getSystemName().isEmpty()) { + resourceData.getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(resource.getName())); + } + + LifecycleStateEnum lifecycleStateEnum = resource.getLifecycleState(); + if (lifecycleStateEnum == null) { + resourceData.getMetadataDataDefinition().setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + } + long currentDate = System.currentTimeMillis(); + if (resource.getCreationDate() == null) { + resourceData.getMetadataDataDefinition().setCreationDate(currentDate); + } + resourceData.getMetadataDataDefinition().setLastUpdateDate(currentDate); + + return resourceData; + } + + private ResourceMetadataData getResourceMetaDataForUpdate(Resource resource) { + // PA - please note: if you add here any fields, make sure they are + // validated (if needed) + // at ResourceBusinessLogic.validateResourceFieldsBeforeUpdate() and + // tested at ResourceBusinessLogicTest. + ResourceMetadataData resourceData = getResourceMetaDataFromResource(resource); + // resourceData.setLastUpdateDate(System.currentTimeMillis()); + // resourceData.setHighestVersion(resource.isHighestVersion()); + // resourceData.setNormalizedName(resource.getNormalizedName()); + // resourceData.setResourceType(resource.getResourceType().name()); + + return resourceData; + } + + public Either<Resource, StorageOperationStatus> getResource(String uniqueId) { + return getResource(uniqueId, false); + } + + public Either<Resource, StorageOperationStatus> getResource(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getResource(uniqueId, componentParametersView, inTransaction); + } + + // public Either<Resource, StorageOperationStatus> getResource(String + // uniqueId, boolean inTransaction) { + // + // Resource resource = null; + // try { + // + // NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either<ResourceMetadataData, StorageOperationStatus> + // componentByLabelAndId = getComponentByLabelAndId(uniqueId, + // resourceNodeType, ResourceMetadataData.class); + // if (componentByLabelAndId.isRight()) { + // return Either.right(componentByLabelAndId.right().value()); + // } + // ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + // resource = convertResourceDataToResource(resourceData); + // + // TitanOperationStatus status = setResourceCreatorFromGraph(resource, + // uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceLastModifierFromGraph(resource, uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourcePropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceAttributesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceDerivedFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentCategoriesFromGraph(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentInstancesFromGraph(uniqueId, resource, + // resourceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // StorageOperationStatus setRequirementsStatus = + // setResourceRequirementsFromGraph(uniqueId, resource, true); + // if (setRequirementsStatus != StorageOperationStatus.OK) { + // log.error("Failed to set requirement of resource " + uniqueId + ". status + // is " + setRequirementsStatus); + // return Either.right(setRequirementsStatus); + // } + // + // StorageOperationStatus storageStatus = + // setResourceCapabilitiesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setArtifactFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // status = setComponentInstancesAttributesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, + // resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // status = setAllVersions(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setGroupsFromGraph(uniqueId, resource, NodeTypeEnum.Resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // } finally { + // if (false == inTransaction) { + // titanGenericDao.commit(); + // } + // } + // + // return Either.left(resource); + // } + + private TitanOperationStatus setComponentInstancesAttributesFromGraph(String uniqueId, Resource component) { + Map<String, List<ComponentInstanceAttribute>> resourceInstancesAttributes = new HashMap<>(); + TitanOperationStatus status = TitanOperationStatus.OK; + List<ComponentInstance> componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + for (ComponentInstance resourceInstance : componentInstances) { + Either<List<ComponentInstanceAttribute>, TitanOperationStatus> eitherRIAttributes = attributeOperation.getAllAttributesOfResourceInstance(resourceInstance); + if (eitherRIAttributes.isRight()) { + status = eitherRIAttributes.right().value(); + break; + } else { + resourceInstancesAttributes.put(resourceInstance.getUniqueId(), eitherRIAttributes.left().value()); + } + } + + component.setComponentInstancesAttributes(resourceInstancesAttributes); + } + + return status; + + } + + // public Either<Resource, StorageOperationStatus> getResource_tx(String + // uniqueId, boolean inTransaction) { + // + // Resource resource = null; + // try { + // + // NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either<ResourceMetadataData, StorageOperationStatus> + // componentByLabelAndId = getComponentByLabelAndId_tx(uniqueId, + // resourceNodeType, ResourceMetadataData.class); + // if (componentByLabelAndId.isRight()) { + // return Either.right(componentByLabelAndId.right().value()); + // } + // ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + // resource = convertResourceDataToResource(resourceData); + // + // TitanOperationStatus status = setResourceCreatorFromGraph(resource, + // uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceLastModifierFromGraph(resource, uniqueId); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourcePropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setResourceDerivedFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentCategoriesFromGraph(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setComponentInstancesFromGraph(uniqueId, resource, + // resourceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // StorageOperationStatus setRequirementsStatus = + // setResourceRequirementsFromGraph(uniqueId, resource, true); + // if (setRequirementsStatus != StorageOperationStatus.OK) { + // log.error("Failed to set requirement of resource " + uniqueId + ". status + // is " + setRequirementsStatus); + // return Either.right(setRequirementsStatus); + // } + // + // StorageOperationStatus storageStatus = + // setResourceCapabilitiesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setArtifactFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // + // } + // + // storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // + // storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, + // resource); + // if (storageStatus != StorageOperationStatus.OK) { + // return Either.right(storageStatus); + // } + // status = setAllVersions(resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // } finally { + // if (false == inTransaction) { + // titanGenericDao.commit(); + // } + // } + // + // return Either.left(resource); + // } + + private StorageOperationStatus setResourceAdditionalInformationFromGraph(String uniqueId, Resource resource) { + + List<AdditionalInformationDefinition> additionalInformation = new ArrayList<>(); + + Either<AdditionalInformationDefinition, StorageOperationStatus> either = additionalInformationOperation.getAllAdditionalInformationParameters(NodeTypeEnum.Resource, uniqueId, true, true); + + if (either.isRight()) { + StorageOperationStatus status = either.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + additionalInformation.add(additionalInformationDefinition); + + resource.setAdditionalInformation(additionalInformation); + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus setResourceInterfacesFromGraph(String uniqueId, Resource resource) { + + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> statusRes = interfaceLifecycleOperation.getAllInterfacesOfResource(uniqueId, true, true); + if (statusRes.isRight()) { + return statusRes.right().value(); + } + Map<String, InterfaceDefinition> value = statusRes.left().value(); + + resource.setInterfaces(value); + + return StorageOperationStatus.OK; + } + + private StorageOperationStatus setResourceCapabilitiesFromGraph(String uniqueId, Resource resource) { + StorageOperationStatus retStatus; + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> result = capabilityOperation.getAllCapabilitiesOfResource(uniqueId, true, true); + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + retStatus = status; + } else { + retStatus = StorageOperationStatus.OK; + } + } else { + Map<String, CapabilityDefinition> capabilities = result.left().value(); + if (capabilities == null || capabilities.isEmpty()) { + Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherCapabilities = super.getCapabilities(resource, NodeTypeEnum.Resource, true); + if (eitherCapabilities.isLeft()) { + retStatus = StorageOperationStatus.OK; + Map<String, List<CapabilityDefinition>> calculatedCapabilities = eitherCapabilities.left().value(); + resource.setCapabilities(calculatedCapabilities); + } else { + retStatus = StorageOperationStatus.GENERAL_ERROR; + } + + } else { + retStatus = StorageOperationStatus.OK; + resource.setCapabilities(capabilityOperation.convertCapabilityMap(capabilities, null, null)); + } + + } + return retStatus; + + } + + public Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> getCapabilities(org.openecomp.sdc.be.model.Component component, NodeTypeEnum componentTypeEnum, boolean inTransaction) { + + try { + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> result = capabilityOperation.getAllCapabilitiesOfResource(component.getUniqueId(), true, true); + if (result.isRight() || result.left().value().isEmpty()) { + final Either<Map<String, List<CapabilityDefinition>>, TitanOperationStatus> eitherCapabilities = super.getCapabilities(component, componentTypeEnum, inTransaction); + return eitherCapabilities; + } else { + return Either.left(capabilityOperation.convertCapabilityMap(result.left().value(), null, null)); + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + } + + public Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> getRequirements(org.openecomp.sdc.be.model.Component component, NodeTypeEnum componentTypeEnum, boolean inTransaction) { + try { + Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = requirementOperation.getAllResourceRequirements(component.getUniqueId(), true); + if (result.isRight() || result.left().value().isEmpty()) { + final Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherCapabilities = super.getRequirements(component, componentTypeEnum, true); + return eitherCapabilities; + } else { + return Either.left(requirementOperation.convertRequirementMap(result.left().value(), null, null)); + } + } finally { + if (inTransaction == false) { + titanGenericDao.commit(); + } + } + + } + + private StorageOperationStatus setResourceRequirementsFromGraph(String uniqueId, Resource resource, boolean inTransaction) { + StorageOperationStatus retStatus; + Either<Map<String, RequirementDefinition>, StorageOperationStatus> result = requirementOperation.getAllResourceRequirements(uniqueId, inTransaction); + ; + if (result.isRight()) { + StorageOperationStatus status = result.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + retStatus = status; + } else { + retStatus = StorageOperationStatus.OK; + } + } else { + Map<String, RequirementDefinition> requirements = result.left().value(); + if (requirements == null || requirements.isEmpty()) { + Either<Map<String, List<RequirementDefinition>>, TitanOperationStatus> eitherCapabilities = super.getRequirements(resource, NodeTypeEnum.Resource, true); + if (eitherCapabilities.isLeft()) { + retStatus = StorageOperationStatus.OK; + Map<String, List<RequirementDefinition>> calculatedCapabilities = eitherCapabilities.left().value(); + resource.setRequirements(calculatedCapabilities); + } else { + retStatus = StorageOperationStatus.GENERAL_ERROR; + } + + } else { + retStatus = StorageOperationStatus.OK; + resource.setRequirements(requirementOperation.convertRequirementMap(requirements, null, null)); + } + + } + return retStatus; + } + + private TitanOperationStatus setResourcePropertiesFromGraph(String uniqueId, Resource resource) { + + List<PropertyDefinition> properties = new ArrayList<>(); + TitanOperationStatus status = propertyOperation.findAllResourcePropertiesRecursively(uniqueId, properties); + if (status == TitanOperationStatus.OK) { + resource.setProperties(properties); + } + + return status; + + } + + private TitanOperationStatus setResourceAttributesFromGraph(String uniqueId, Resource resource) { + + List<AttributeDefinition> attributes = new ArrayList<>(); + TitanOperationStatus status = attributeOperation.findAllResourceAttributesRecursively(uniqueId, attributes); + if (status == TitanOperationStatus.OK) { + resource.setAttributes(attributes); + } + + return status; + + } + + private TitanOperationStatus setResourceDerivedFromGraph(String uniqueId, Resource resource) { + List<String> derivedFromList = new ArrayList<String>(); + + TitanOperationStatus listFromGraphStatus = fillResourceDerivedListFromGraph(uniqueId, derivedFromList); + if (!TitanOperationStatus.OK.equals(listFromGraphStatus)) { + return listFromGraphStatus; + } + + if (false == derivedFromList.isEmpty()) { + if (derivedFromList.size() > 1) { + List<String> lastDerivedFrom = new ArrayList<String>(); + lastDerivedFrom.add(derivedFromList.get(1)); + resource.setDerivedFrom(lastDerivedFrom); + resource.setDerivedList(derivedFromList); + } else { + resource.setDerivedFrom(null); + resource.setDerivedList(derivedFromList); + } + + } + + return TitanOperationStatus.OK; + } + + public TitanOperationStatus fillResourceDerivedListFromGraph(String uniqueId, List<String> derivedFromList) { + // Either<List<ImmutablePair<ResourceMetadataData, GraphEdge>>, + // TitanOperationStatus> childrenNodes = + // titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + // uniqueId, GraphEdgeLabels.DERIVED_FROM, + // NodeTypeEnum.Resource, ResourceMetadataData.class); + // + // if (childrenNodes.isRight() && (childrenNodes.right().value() != + // TitanOperationStatus.NOT_FOUND)) { + // return childrenNodes.right().value(); + // } else if (childrenNodes.isLeft()) { + // + // List<ImmutablePair<ResourceMetadataData, GraphEdge>> pairList = + // childrenNodes.left().value(); + // for (ImmutablePair<ResourceMetadataData, GraphEdge> pair : pairList) + // { + // derivedFromList.add(pair.left.getMetadataDataDefinition().getName()); + // return + // fillResourceDerivedListFromGraph(pair.left.getMetadataDataDefinition().getUniqueId(), + // derivedFromList); + // } + // } + List<ResourceMetadataData> derivedData = new ArrayList<ResourceMetadataData>(); + TitanOperationStatus findResourcesPathRecursively = findResourcesPathRecursively(uniqueId, derivedData); + if (!findResourcesPathRecursively.equals(TitanOperationStatus.OK)) { + return findResourcesPathRecursively; + } + derivedData.forEach(resourceData -> derivedFromList.add(((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()).getToscaResourceName())); + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setResourceLastModifierFromGraph(Resource resource, String resourceId) { + + Either<ImmutablePair<UserData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.LAST_MODIFIER, NodeTypeEnum.User, + UserData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + ImmutablePair<UserData, GraphEdge> value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + + if (log.isDebugEnabled()) { + log.debug("Build resource : set last modifier userId to {}", userData.getUserId()); + } + + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set last modifier full name to {}", fullName); + resource.setLastUpdaterUserId(userData.getUserId()); + resource.setLastUpdaterFullName(fullName); + + return TitanOperationStatus.OK; + } + + private TitanOperationStatus setResourceCreatorFromGraph(Resource resource, String resourceId) { + + Either<ImmutablePair<UserData, GraphEdge>, TitanOperationStatus> parentNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.CREATOR, NodeTypeEnum.User, UserData.class); + if (parentNode.isRight()) { + log.debug("Failed to find the creator of resource {}", resourceId); + return parentNode.right().value(); + } + + ImmutablePair<UserData, GraphEdge> value = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + UserData userData = value.getKey(); + if (log.isDebugEnabled()) { + log.debug("Build resource : set creator userId to {}", userData.getUserId()); + } + String fullName = buildFullName(userData); + if (log.isDebugEnabled()) + log.debug("Build resource : set creator full name to {}", fullName); + resource.setCreatorUserId(userData.getUserId()); + resource.setCreatorFullName(fullName); + + return TitanOperationStatus.OK; + } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component resource) { + String uniqueId = resource.getUniqueId(); + Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqueId, GraphEdgeLabels.CATEGORY, + NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + List<ImmutablePair<SubCategoryData, GraphEdge>> listValue = parentNode.left().value(); + log.debug("Result after looking for subcategory nodes pointed by resource {}. status is {}", uniqueId, listValue); + if (listValue.size() > 1) { + log.error("Multiple edges foud between resource {} to subcategory nodes.", uniqueId); + } + ImmutablePair<SubCategoryData, GraphEdge> value = listValue.get(0); + log.debug("Found parent node {}", value); + + SubCategoryData subcategoryData = value.getKey(); + + Either<ImmutablePair<CategoryData, GraphEdge>, TitanOperationStatus> categoryNode = titanGenericDao.getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceSubcategory), (String) subcategoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryNode.isRight()) { + return categoryNode.right().value(); + } + + CategoryData categoryData = categoryNode.left().value().left; + CategoryDefinition catDef = new CategoryDefinition(categoryData.getCategoryDataDefinition()); + SubCategoryDefinition subcatDef = new SubCategoryDefinition(subcategoryData.getSubCategoryDataDefinition()); + + resource.addCategory(catDef, subcatDef); + return TitanOperationStatus.OK; + } + + public String buildFullName(UserData userData) { + + String fullName = userData.getFirstName(); + if (fullName == null) { + fullName = ""; + } else { + fullName = fullName + " "; + } + String lastName = userData.getLastName(); + if (lastName != null) { + fullName += lastName; + } + return fullName; + } + + private Resource convertResourceDataToResource(ResourceMetadataData resourceData) { + + ResourceMetadataDefinition resourceMetadataDataDefinition = new ResourceMetadataDefinition((ResourceMetadataDataDefinition) resourceData.getMetadataDataDefinition()); + + Resource resource = new Resource(resourceMetadataDataDefinition); + + return resource; + } + + @Override + public Either<Resource, StorageOperationStatus> deleteResource(String resourceId) { + return deleteResource(resourceId, false); + } + + @Override + public Either<Resource, StorageOperationStatus> updateResource(Resource resource) { + + return updateResource(resource, false); + + } + + @Override + public Either<Integer, StorageOperationStatus> getNumberOfResourcesByName(String resourceName) { + + Map<String, Object> propertiesToMatch = new HashMap<String, Object>(); + propertiesToMatch.put(GraphPropertiesDictionary.NAME.getProperty(), resourceName); + + Either<List<ResourceMetadataData>, TitanOperationStatus> getParentResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + log.debug("result after searching for resources called " + resourceName + " is " + getParentResources); + if (getParentResources.isRight()) { + TitanOperationStatus titanStatus = getParentResources.right().value(); + if (titanStatus == TitanOperationStatus.NOT_FOUND) { + log.debug("Number of returned resources is 0."); + return Either.left(0); + } + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus)); + } else { + List<ResourceMetadataData> value = getParentResources.left().value(); + int numberOFResources = (value == null ? 0 : value.size()); + log.debug("The number of resources returned after searching for resource called " + resourceName + " is " + numberOFResources); + return Either.left(numberOFResources); + } + } + + public PropertyOperation getPropertyOperation() { + return propertyOperation; + } + + public void setPropertyOperation(PropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + public RequirementOperation getRequirementOperation() { + return requirementOperation; + } + + public void setRequirementOperation(RequirementOperation requirementOperation) { + this.requirementOperation = requirementOperation; + } + + public CapabilityOperation getCapabilityOperation() { + return capabilityOperation; + } + + public void setCapabilityOperation(CapabilityOperation capabilityOperation) { + this.capabilityOperation = capabilityOperation; + } + + public IArtifactOperation getArtifactOperation() { + return artifactOperation; + } + + public void setArtifactOperation(IArtifactOperation artifactOperation) { + this.artifactOperation = artifactOperation; + } + + public InterfaceLifecycleOperation getInterfaceLifecycleOperation() { + return interfaceLifecycleOperation; + } + + public void setInterfaceLifecycleOperation(InterfaceLifecycleOperation interfaceLifecycleOperation) { + this.interfaceLifecycleOperation = interfaceLifecycleOperation; + } + + public TitanGenericDao getTitanGenericDao() { + return titanGenericDao; + } + + public IElementOperation getElementOperation() { + return elementOperation; + } + + public void setElementOperation(IElementOperation elementOperation) { + this.elementOperation = elementOperation; + } + + /** + * FOR TEST ONLY + * + * @param titanGenericDao + */ + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract) { + + return getAllCertifiedResources(isAbstract, null); + + } + + @Override + /** + * Deletes the resource node, property nodes and relation to artifacts. MUST handle deletion of artifact from artifacts repository outside this method (in catalog-be) + */ + public Either<Resource, StorageOperationStatus> deleteResource(String resourceId, boolean inTransaction) { + + Either<Resource, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + TitanGraph titanGraph = graphResult.left().value(); + Iterable<TitanVertex> vertecies = titanGraph.query().has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId).vertices(); + Either<Resource, StorageOperationStatus> resourceEither = getResource(resourceId, true); + Resource resource = resourceEither.left().value(); + if (vertecies != null && resourceEither.isLeft()) { + Iterator<TitanVertex> iterator = vertecies.iterator(); + if (iterator != null && iterator.hasNext()) { + Vertex rootVertex = iterator.next(); + TitanOperationStatus deleteChildrenNodes = graphDeleteUtil.deleteChildrenNodes(rootVertex, GraphEdgeLabels.PROPERTY); + log.debug("After deleting properties nodes in the graph. status is " + deleteChildrenNodes); + if (deleteChildrenNodes != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(deleteChildrenNodes)); + return result; + } + StorageOperationStatus removeInterfacesFromResource = removeInterfacesFromResource(resource); + log.debug("After deleting interfaces nodes in the graph. status is " + removeInterfacesFromResource); + if (!removeInterfacesFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeInterfacesFromResource); + return result; + } + StorageOperationStatus removeArtifactsFromResource = removeArtifactsFromResource(resource); + log.debug("After deleting artifacts nodes in the graph. status is " + removeArtifactsFromResource); + if (!removeArtifactsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeArtifactsFromResource); + return result; + } + StorageOperationStatus removeCapabilitiesFromResource = removeCapabilitiesFromResource(resource); + log.debug("After deleting capabilities nodes in the graph. status is " + removeCapabilitiesFromResource); + if (!removeCapabilitiesFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeCapabilitiesFromResource); + return result; + } + + StorageOperationStatus removeRequirementsFromResource = removeRequirementsFromResource(resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeRequirementsFromResource); + if (!removeRequirementsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeRequirementsFromResource); + return result; + } + + StorageOperationStatus removeRIsFromResource = removeResourceInstanceFromResource(resource); + log.debug("After deleting resource instance nodes in the graph. status is " + removeRIsFromResource); + if (!removeRIsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeRIsFromResource); + return result; + } + + StorageOperationStatus removeAttributesFromResource = removeAttributesFromResource(resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeRequirementsFromResource); + if (removeAttributesFromResource != StorageOperationStatus.OK) { + result = Either.right(removeAttributesFromResource); + return result; + } + + StorageOperationStatus removeInputsFromResource = removeInputsFromComponent(NodeTypeEnum.Resource, resource); + log.debug("After deleting requirements nodes in the graph. status is " + removeInputsFromResource); + if (removeInputsFromResource != StorageOperationStatus.OK) { + result = Either.right(removeInputsFromResource); + return result; + } + + StorageOperationStatus removeAdditionalInformationFromResource = super.deleteAdditionalInformation(NodeTypeEnum.Resource, resource.getUniqueId()); + log.debug("After deleting additional information node in the graph. status is " + removeAdditionalInformationFromResource); + if (!removeAdditionalInformationFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeAdditionalInformationFromResource); + return result; + } + + StorageOperationStatus removeGroupsFromResource = super.deleteGroups(NodeTypeEnum.Resource, resource.getUniqueId()); + log.debug("After deleting group nodes in the graph. status is " + removeGroupsFromResource); + if (!removeGroupsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeGroupsFromResource); + return result; + } + + rootVertex.remove(); + + } else { + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + } else { + result = Either.right(StorageOperationStatus.NOT_FOUND); + return result; + } + + result = Either.left(resource); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("deleteResource operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteResource operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + private StorageOperationStatus removeAttributesFromResource(Resource resource) { + Either<Map<String, AttributeDefinition>, StorageOperationStatus> deleteAllAttributeAssociatedToNode = attributeOperation.deleteAllAttributeAssociatedToNode(NodeTypeEnum.Resource, resource.getUniqueId()); + return deleteAllAttributeAssociatedToNode.isRight() ? deleteAllAttributeAssociatedToNode.right().value() : StorageOperationStatus.OK; + } + + private StorageOperationStatus removeArtifactsFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + Map<String, ArtifactDefinition> allArtifacts = new HashMap<String, ArtifactDefinition>(); + if (resource.getArtifacts() != null) { + allArtifacts.putAll(resource.getArtifacts()); + } + if (resource.getDeploymentArtifacts() != null) { + allArtifacts.putAll(resource.getDeploymentArtifacts()); + } + if (allArtifacts != null) { + for (Entry<String, ArtifactDefinition> entry : allArtifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = entry.getValue(); + Either<ArtifactDefinition, StorageOperationStatus> removeArifactFromResource = artifactOperation.removeArifactFromResource(resourceId, artifactDefinition.getUniqueId(), NodeTypeEnum.Resource, true, true); + if (removeArifactFromResource.isRight()) { + return removeArifactFromResource.right().value(); + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeInterfacesFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + // delete only interfaces of this resource (not interfaces derived) + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceId, false, true); + if (allInterfacesOfResource.isRight()) { + log.error("failed to get interfaces for resource {}. status is {}", resourceId, allInterfacesOfResource.right().value()); + return allInterfacesOfResource.right().value(); + } + Map<String, InterfaceDefinition> interfaces = allInterfacesOfResource.left().value(); + if (interfaces != null) { + for (Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { + Boolean isAbstract = resource.isAbstract(); + + InterfaceDefinition interfaceDefinition = entry.getValue(); + // esofer - in case the resource is abstract, we deleting only + // the edge to the interface. + if (isAbstract != null && true == isAbstract.booleanValue()) { + log.debug("Going to dissociate resource {} from interface {}", resourceId, interfaceDefinition.getUniqueId()); + UniqueIdData uniqueIdData = new UniqueIdData(NodeTypeEnum.Resource, resourceId); + Either<InterfaceDefinition, StorageOperationStatus> dissociateInterfaceFromNode = interfaceLifecycleOperation.dissociateInterfaceFromNode(uniqueIdData, interfaceDefinition); + if (dissociateInterfaceFromNode.isRight()) { + log.error("failed to dissociate resource {} from interface {}. status is {}", resourceId, interfaceDefinition.getUniqueId(), dissociateInterfaceFromNode.right().value()); + return dissociateInterfaceFromNode.right().value(); + } + } else { + Either<InterfaceDefinition, StorageOperationStatus> deleteInterfaceOfResourceOnGraph = interfaceLifecycleOperation.deleteInterfaceOfResourceOnGraph(resourceId, interfaceDefinition, true); + if (deleteInterfaceOfResourceOnGraph.isRight()) { + return deleteInterfaceOfResourceOnGraph.right().value(); + } + } + } + } + return StorageOperationStatus.OK; + } + + private StorageOperationStatus removeCapabilitiesFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> deleteAllRes = capabilityOperation.deleteAllCapabilities(resourceId, true); + if (deleteAllRes.isRight()) { + StorageOperationStatus status = deleteAllRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus removeRequirementsFromResource(Resource resource) { + + String resourceId = resource.getUniqueId(); + + Either<Map<String, RequirementDefinition>, StorageOperationStatus> deleteAllRes = requirementOperation.deleteAllRequirements(resourceId, true); + + if (deleteAllRes.isRight()) { + StorageOperationStatus status = deleteAllRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + + return StorageOperationStatus.OK; + + } + + private StorageOperationStatus removeResourceInstanceFromResource(Resource resource) { + String resourceId = resource.getUniqueId(); + + Either<List<ComponentInstance>, StorageOperationStatus> deleteAllResourceInstancesRes = componentInstanceOperation.deleteAllComponentInstances(resourceId, NodeTypeEnum.Resource, true); + if (deleteAllResourceInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllResourceInstancesRes.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + return StorageOperationStatus.OK; + } + return status; + } + return StorageOperationStatus.OK; + } + + @Override + public Either<Resource, StorageOperationStatus> updateResource(Resource resource, boolean inTransaction) { + return (Either<Resource, StorageOperationStatus>) updateComponent(resource, inTransaction, titanGenericDao, resource.getClass(), NodeTypeEnum.Resource); + + } + + @Override + protected <T extends Component> StorageOperationStatus updateDerived(Component component, Component currentComponent, ComponentMetadataData updatedResourceData, Class<T> clazz) { + Resource resource = (Resource) component; + Resource currentResource = (Resource) currentComponent; + if (resource.getDerivedFrom() != null) {// meaning derived from changed + + Either<List<ResourceMetadataData>, StorageOperationStatus> findDerivedResourcesOld = findDerivedResources(currentResource); + if (findDerivedResourcesOld.isRight()) { + log.debug("Couldn't find derived resource {} for current resource in the graph", currentResource.getDerivedFrom().get(0)); + return findDerivedResourcesOld.right().value(); + } + + List<ResourceMetadataData> oldDerived = findDerivedResourcesOld.left().value(); + if (oldDerived.isEmpty()) { + log.debug("Derived from list fetched from DB for current resource is empty"); + return StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND; + } + + Either<List<ResourceMetadataData>, StorageOperationStatus> findDerivedResourcesNew = findDerivedResources((Resource) resource); + if (findDerivedResourcesNew.isRight()) { + log.debug("Couldn't find derived resource {} for update resource in the graph", resource.getDerivedFrom().get(0)); + return findDerivedResourcesNew.right().value(); + } + + List<ResourceMetadataData> newDerived = findDerivedResourcesNew.left().value(); + if (newDerived.isEmpty()) { + log.debug("Derived from list fetched from DB for updated resource is empty"); + return StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND; + } + + Either<Boolean, TitanOperationStatus> reassociateDerivedFrom = reassociateDerivedFrom((ResourceMetadataData) updatedResourceData, oldDerived, newDerived); + if (reassociateDerivedFrom.isRight()) { + log.debug("Couldn't change derived from for the resoure"); + return DaoStatusConverter.convertTitanStatusToStorageStatus(reassociateDerivedFrom.right().value()); + } + } + return StorageOperationStatus.OK; + } + + private Either<Boolean, TitanOperationStatus> reassociateDerivedFrom(ResourceMetadataData resourceData, List<ResourceMetadataData> oldDerived, List<ResourceMetadataData> newDerived) { + ResourceMetadataData oldDerivedNode = oldDerived.get(0); + log.debug("Dissociating resource {} from old parent resource {}", resourceData.getUniqueId(), oldDerivedNode.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> deleteRelation = titanGenericDao.deleteRelation(resourceData, oldDerivedNode, GraphEdgeLabels.DERIVED_FROM); + if (deleteRelation.isRight()) { + log.debug("Failed to dissociate resource {} from old parent resource {}", resourceData.getUniqueId(), oldDerivedNode.getUniqueId()); + return Either.right(deleteRelation.right().value()); + } + ResourceMetadataData newDerivedNode = newDerived.get(0); + log.debug("Associating resource {} with new parent resource {}", resourceData.getUniqueId(), newDerivedNode.getUniqueId()); + Either<GraphRelation, TitanOperationStatus> addRelation = titanGenericDao.createRelation(resourceData, newDerivedNode, GraphEdgeLabels.DERIVED_FROM, null); + if (addRelation.isRight()) { + log.debug("Failed to associate resource {} with new parent resource {}", resourceData.getUniqueId(), newDerivedNode.getUniqueId()); + return Either.right(addRelation.right().value()); + } + + return Either.left(true); + } + + private StorageOperationStatus moveCategoryEdge(Resource resource, ResourceMetadataData resourceData, CategoryDefinition newCategory) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation categoryRelation = new GraphRelation(); + categoryRelation.setType(GraphEdgeLabels.CATEGORY.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Resource, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId()); + categoryRelation.setFrom(relationEndPoint); + Either<GraphRelation, TitanOperationStatus> deleteOutgoingRelation = titanGenericDao.deleteOutgoingRelation(categoryRelation); + if (deleteOutgoingRelation.isRight()) { + log.error("Failed to delete category from resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.CATEGORY); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteOutgoingRelation.right().value()); + return result; + } + + log.debug("After removing edge from graph " + deleteOutgoingRelation); + + return assosiateMetadataToCategory(resource, resourceData); + } + + private StorageOperationStatus moveLastModifierEdge(Resource resource, ResourceMetadataData resourceData, UserData modifierUserData) { + + StorageOperationStatus result = StorageOperationStatus.OK; + + GraphRelation lastModifierRelation = new GraphRelation(); + lastModifierRelation.setType(GraphEdgeLabels.LAST_MODIFIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Resource, UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId()); + lastModifierRelation.setTo(relationEndPoint); + Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation = titanGenericDao.deleteIncomingRelation(lastModifierRelation); + if (deleteIncomingRelation.isRight()) { + log.error("Failed to delete user from resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return result; + } + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(modifierUserData, resourceData, GraphEdgeLabels.LAST_MODIFIER, null); + log.debug("After associating user " + modifierUserData + " to resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + if (createRelation.isRight()) { + log.error("Failed to associate user " + modifierUserData + " to resource " + resourceData.getUniqueId() + ". Edge type is " + GraphEdgeLabels.LAST_MODIFIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return result; + } + + return result; + } + + private Either<ResourceMetadataData, TitanOperationStatus> findResource(String resourceId) { + + String key = UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource); + Either<ResourceMetadataData, TitanOperationStatus> findResource = titanGenericDao.getNode(key, resourceId, ResourceMetadataData.class); + + return findResource; + } + + private StorageOperationStatus setArtifactFromGraph(String uniqueId, Resource resource) { + StorageOperationStatus result = StorageOperationStatus.OK; + Either<Map<String, ArtifactDefinition>, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(uniqueId, NodeTypeEnum.Resource, true); + if (artifacts.isRight()) { + result = artifacts.right().value(); + } else { + createSpecificArtifactList(resource, artifacts.left().value()); + } + return result; + } + + @Override + public <T extends Component> Either<T, StorageOperationStatus> getComponent(String id, Class<T> clazz) { + + Either<Resource, StorageOperationStatus> component = getResource(id); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return Either.left(clazz.cast(component.left().value())); + } + + @Override + public Either<Boolean, StorageOperationStatus> validateResourceNameExists(String resourceName, ResourceTypeEnum resourceType) { + if (resourceType != null) { + Map<String, Object> properties = new HashMap<String, Object>(); + properties.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + if (resourceType.equals(ResourceTypeEnum.VF)) { + return validateResourceNameUniqueness(resourceName, properties, null, titanGenericDao); + } else { + return validateResourceNameUniqueness(resourceName, null, properties, titanGenericDao); + } + + } else { + return validateResourceNameUniqueness(resourceName, null, null, titanGenericDao); + } + + } + + public Either<Boolean, StorageOperationStatus> validateToscaResourceNameExists(String templateName) { + return validateToscaResourceNameUniqueness(templateName, titanGenericDao); + } + + public Either<List<ArtifactDefinition>, StorageOperationStatus> getAdditionalArtifacts(String resourceId, boolean recursively, boolean inTransaction) { + List<ArtifactDefinition> artifacts = new ArrayList<>(); + + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(resourceId, false, true); + if (interfacesOfResource.isRight()) { + log.error("failed to get all resource interfaces. resource id={}. status ={}", resourceId, interfacesOfResource.right().value()); + return Either.right(interfacesOfResource.right().value()); + } + + Map<String, InterfaceDefinition> interfaces = interfacesOfResource.left().value(); + if (interfaces != null && !interfaces.isEmpty()) { + for (Entry<String, InterfaceDefinition> entry : interfaces.entrySet()) { + + InterfaceDefinition interfaceDefinition = entry.getValue(); + Map<String, Operation> operations = interfaceDefinition.getOperations(); + if (operations != null && !operations.isEmpty()) { + for (Entry<String, Operation> opEntry : operations.entrySet()) { + + Operation operation = opEntry.getValue(); + ArtifactDefinition artifactDefinition = operation.getImplementation(); + if (artifactDefinition != null) { + artifacts.add(artifactDefinition); + } + } + } + } + } + return Either.left(artifacts); + } + + @SuppressWarnings("unchecked") + public Either<List<Resource>, StorageOperationStatus> getFollowed(String userId, Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction) { + return (Either<List<Resource>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getFollowedComponent(userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Resource); + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getResource(id, inTransaction); + } + + private Optional<ImmutablePair<SubCategoryData, GraphEdge>> validateCategoryHierarcy(List<ImmutablePair<SubCategoryData, GraphEdge>> childNodes, String subCategoryName) { + Predicate<ImmutablePair<SubCategoryData, GraphEdge>> matchName = p -> p.getLeft().getSubCategoryDataDefinition().getName().equals(subCategoryName); + return childNodes.stream().filter(matchName).findAny(); + } + + private Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> getAllSubCategories(String categoryName) { + Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation.getNewCategoryData(categoryName, NodeTypeEnum.ResourceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + return Either.right(categoryResult.right().value()); + } + CategoryData categoryData = categoryResult.left().value(); + + Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, TitanOperationStatus> childrenNodes = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), (String) categoryData.getUniqueId(), + GraphEdgeLabels.SUB_CATEGORY, NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + if (childrenNodes.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(childrenNodes.right().value())); + } + return Either.left(childrenNodes.left().value()); + } + + @Override + public <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, boolean inTransaction) { + + String subCategoryName = filters.get(FilterKeyEnum.SUB_CATEGORY); + String categoryName = filters.get(FilterKeyEnum.CATEGORY); + Either<List<ImmutablePair<SubCategoryData, GraphEdge>>, StorageOperationStatus> subcategories = null; + Optional<ImmutablePair<SubCategoryData, GraphEdge>> subCategoryData = null; + + if (categoryName != null) { + subcategories = getAllSubCategories(categoryName); + if (subcategories.isRight()) { + filters.remove(FilterKeyEnum.SUB_CATEGORY); + return Either.right(subcategories.right().value()); + } + } + if (subCategoryName != null) { // primary filter + if (categoryName != null) { + subCategoryData = validateCategoryHierarcy(subcategories.left().value(), subCategoryName); + if (!subCategoryData.isPresent()) { + return Either.right(StorageOperationStatus.MATCH_NOT_FOUND); + } + return fetchByCategoryOrSubCategoryUid((String) subCategoryData.get().getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, + ResourceMetadataData.class); + } + + return fetchByCategoryOrSubCategoryName(subCategoryName, NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, inTransaction, ResourceMetadataData.class); + } + return fetchByMainCategory(subcategories.left().value(), inTransaction); + } + + private <T> Either<List<T>, StorageOperationStatus> fetchByMainCategory(List<ImmutablePair<SubCategoryData, GraphEdge>> subcategories, boolean inTransaction) { + List<T> components = new ArrayList<>(); + + for (ImmutablePair<SubCategoryData, GraphEdge> subCategory : subcategories) { + Either<List<T>, StorageOperationStatus> fetched = fetchByCategoryOrSubCategoryUid((String) subCategory.getLeft().getUniqueId(), NodeTypeEnum.ResourceSubcategory, GraphEdgeLabels.SUB_CATEGORY.getProperty(), NodeTypeEnum.Resource, + inTransaction, ResourceMetadataData.class); + if (fetched.isRight()) { + // return fetched; + continue; + } + components.addAll(fetched.left().value()); + } + return Either.left(components); + } + + @Override + public <T> Either<T, StorageOperationStatus> getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Resource, inTransaction); + } + + // will be implement later + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getResourceMetaDataFromResource((Resource) component); + } + + @Override + public Either<Set<Resource>, StorageOperationStatus> getCatalogData(Map<String, Object> propertiesToMatch, boolean inTransaction) { + return getComponentCatalogData(NodeTypeEnum.Resource, propertiesToMatch, Resource.class, ResourceMetadataData.class, inTransaction); + } + + protected TitanOperationStatus findResourcesPathRecursively(String resourceId, List<ResourceMetadataData> resourcesPathList) { + + Either<ResourceMetadataData, TitanOperationStatus> nodeRes = this.titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, ResourceMetadataData.class); + + if (nodeRes.isRight()) { + TitanOperationStatus status = nodeRes.right().value(); + log.error("Failed to fetch resource {} . status is {}", resourceId, status); + return status; + } + + ResourceMetadataData resourceData = nodeRes.left().value(); + resourcesPathList.add(resourceData); + Either<ImmutablePair<ResourceMetadataData, GraphEdge>, TitanOperationStatus> parentResourceRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resourceId, GraphEdgeLabels.DERIVED_FROM, + NodeTypeEnum.Resource, ResourceMetadataData.class); + + while (parentResourceRes.isLeft()) { + + ImmutablePair<ResourceMetadataData, GraphEdge> value = parentResourceRes.left().value(); + ResourceMetadataData parentResourceData = value.getKey(); + + resourcesPathList.add(parentResourceData); + + parentResourceRes = titanGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), parentResourceData.getMetadataDataDefinition().getUniqueId(), GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, + ResourceMetadataData.class); + } + + TitanOperationStatus operationStatus = parentResourceRes.right().value(); + + if (operationStatus != TitanOperationStatus.NOT_FOUND) { + return operationStatus; + } else { + return TitanOperationStatus.OK; + } + + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> updateComponent(T component, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) updateResource((Resource) component, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either<Component, StorageOperationStatus> deleteComponent(String id, boolean inTransaction) { + return (Either<Component, StorageOperationStatus>) (Either<?, StorageOperationStatus>) deleteResource(id, inTransaction); + } + + @Override + public Either<Resource, StorageOperationStatus> getLatestByToscaResourceName(String toscaResourceName, boolean inTransaction) { + return getLatestByName(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaResourceName, inTransaction); + + } + + @Override + public Either<Resource, StorageOperationStatus> getLatestByName(String resourceName, boolean inTransaction) { + return getLatestByName(GraphPropertiesDictionary.NAME.getProperty(), resourceName, inTransaction); + + } + + private Either<Resource, StorageOperationStatus> getLatestByName(String property, String resourceName, boolean inTransaction) { + Either<Resource, StorageOperationStatus> result = null; + try { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(property, resourceName); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either<List<ResourceMetadataData>, TitanOperationStatus> highestResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestResources.isRight()) { + TitanOperationStatus status = highestResources.right().value(); + log.debug("failed to find resource with name {}. status={} ", resourceName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<ResourceMetadataData> resources = highestResources.left().value(); + double version = 0.0; + ResourceMetadataData highestResource = null; + for (ResourceMetadataData resource : resources) { + double resourceVersion = Double.parseDouble(resource.getMetadataDataDefinition().getVersion()); + if (resourceVersion > version) { + version = resourceVersion; + highestResource = resource; + } + } + result = getResource(highestResource.getMetadataDataDefinition().getUniqueId(), true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("getLatestByName operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("getLatestByName operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + + @SuppressWarnings("unchecked") + @Override + public Either<List<Resource>, StorageOperationStatus> getTesterFollowed(String userId, Set<LifecycleStateEnum> lifecycleStates, boolean inTransaction) { + return (Either<List<Resource>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getTesterFollowedComponent(userId, lifecycleStates, inTransaction, NodeTypeEnum.Resource); + } + + @Override + public Either<List<Resource>, StorageOperationStatus> getResourceCatalogData(boolean inTransaction) { + return getResourceCatalogData(inTransaction, null); + } + + private Either<List<Resource>, StorageOperationStatus> getResourceCatalogData(boolean inTransaction, Map<String, Object> otherToMatch) { + + long start = System.currentTimeMillis(); + + long startFetchAllStates = System.currentTimeMillis(); + Map<String, Object> propertiesToMatchHigest = new HashMap<>(); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + propertiesToMatchHigest.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), false); + Either<List<ResourceMetadataData>, TitanOperationStatus> allHighestStates = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatchHigest, ResourceMetadataData.class); + if (allHighestStates.isRight() && allHighestStates.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(allHighestStates.right().value())); + } + + if (allHighestStates.isRight()) { + return Either.left(new ArrayList<>()); + } + List<ResourceMetadataData> list = allHighestStates.left().value(); + + List<ResourceMetadataData> certified = new ArrayList<>(); + List<ResourceMetadataData> noncertified = new ArrayList<>(); + for (ResourceMetadataData reData : list) { + if (reData.getMetadataDataDefinition().getState().equals(LifecycleStateEnum.CERTIFIED.name())) { + certified.add(reData); + } else { + noncertified.add(reData); + } + } + + long endFetchAll = System.currentTimeMillis(); + log.debug("Fetch catalog resources all states: certified {}, noncertified {}", certified.size(), noncertified.size()); + log.debug("Fetch catalog resources all states from graph took {} ms", endFetchAll - startFetchAllStates); + + try { + List<ResourceMetadataData> notCertifiedHighest = noncertified; + List<ResourceMetadataData> certifiedHighestList = certified; + + HashMap<String, String> VFNames = new HashMap<>(); + HashMap<String, String> VFCNames = new HashMap<>(); + for (ResourceMetadataData data : notCertifiedHighest) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (((ResourceMetadataDataDefinition) data.getMetadataDataDefinition()).getResourceType().equals(ResourceTypeEnum.VF)) { + VFNames.put(serviceName, serviceName); + } else { + VFCNames.put(serviceName, serviceName); + } + } + + for (ResourceMetadataData data : certifiedHighestList) { + String serviceName = data.getMetadataDataDefinition().getName(); + if (((ResourceMetadataDataDefinition) data.getMetadataDataDefinition()).getResourceType().equals(ResourceTypeEnum.VF)) { + if (!VFNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } else { + if (!VFCNames.containsKey(serviceName)) { + notCertifiedHighest.add(data); + } + } + } + + long endFetchAllFromGraph = System.currentTimeMillis(); + log.debug("Fetch all catalog resources metadata from graph took {} ms", endFetchAllFromGraph - start); + + long startFetchAllFromCache = System.currentTimeMillis(); + + List<Resource> result = new ArrayList<>(); + + Map<String, Long> components = notCertifiedHighest.stream().collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsForCatalog = componentCache.getComponentsForCatalog(components, ComponentTypeEnum.RESOURCE); + if (componentsForCatalog.isLeft()) { + ImmutablePair<List<Component>, Set<String>> immutablePair = componentsForCatalog.left().value(); + List<Component> foundComponents = immutablePair.getLeft(); + if (foundComponents != null) { + foundComponents.forEach(p -> result.add((Resource) p)); + log.debug("The number of resources added to catalog from cache is {}", foundComponents.size()); + + List<String> foundComponentsUid = foundComponents.stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream().filter(p -> false == foundComponentsUid.contains(p.getUniqueId())).collect(Collectors.toList()); + } + Set<String> nonCachedComponents = immutablePair.getRight(); + int numberNonCached = nonCachedComponents == null ? 0 : nonCachedComponents.size(); + log.debug("The number of left resources for catalog is {}", numberNonCached); + + } + + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog resources metadata from cache took " + (endFetchAllFromCache - startFetchAllFromCache) + " ms"); + + long startFetchFromGraph = System.currentTimeMillis(); + log.debug("The number of resources needed to be fetch as light component is {}", notCertifiedHighest.size()); + for (ResourceMetadataData data : notCertifiedHighest) { + String uniqueId = data.getMetadataDataDefinition().getUniqueId(); + log.trace("Fetch catalog resource non cached {} {}", uniqueId, data.getMetadataDataDefinition().getName()); + Either<Resource, StorageOperationStatus> component = getLightComponent(uniqueId, inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + long endFetchFromGraph = System.currentTimeMillis(); + log.debug("Fetch catalog resources from graph took " + (endFetchFromGraph - startFetchFromGraph) + " ms"); + + return Either.left(result); + + } finally { + long end = System.currentTimeMillis(); + log.debug("Fetch all catalog resources took {} ms", end - start); + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + } + + public Either<List<Resource>, StorageOperationStatus> getResourceCatalogDataVFLatestCertifiedAndNonCertified(boolean inTransaction) { + Map<String, Object> propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + + return getResourceCatalogDataLatestCertifiedAndNonCertified(inTransaction, propertiesToMatch); + } + + private Either<List<Resource>, StorageOperationStatus> getResourceCatalogDataLatestCertifiedAndNonCertified(boolean inTransaction, Map<String, Object> otherToMatch) { + Map<String, Object> propertiesToMatch = new HashMap<>(); + + if (otherToMatch != null) { + propertiesToMatch.putAll(otherToMatch); + } + + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either<List<ResourceMetadataData>, TitanOperationStatus> lastVersionNodes = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + + List<Resource> result = new ArrayList<>(); + + if (lastVersionNodes.isRight() && lastVersionNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(lastVersionNodes.right().value())); + } + + List<ResourceMetadataData> listOfHighest; + + if (lastVersionNodes.isLeft()) { + listOfHighest = lastVersionNodes.left().value(); + } else { + return Either.left(result); + } + + for (ResourceMetadataData data : listOfHighest) { + Either<Resource, StorageOperationStatus> component = getLightComponent(data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + return Either.left(result); + } + + private Either<List<Resource>, StorageOperationStatus> getResourceListByCriteria(Map<String, Object> props, boolean inTransaction) { + + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()); + + Either<List<ResourceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List<Resource> resources = new ArrayList<Resource>(); + List<ResourceMetadataData> resourcesDataList = byCriteria.left().value(); + for (ResourceMetadataData data : resourcesDataList) { + Either<Resource, StorageOperationStatus> resource = getResource(data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (resource.isLeft()) { + resources.add(resource.left().value()); + } else { + log.debug("Failed to fetch resource for name = " + data.getMetadataDataDefinition().getName() + " and id = " + data.getUniqueId()); + } + } + return Either.left(resources); + } + + public Either<List<Resource>, StorageOperationStatus> getResourceListByUuid(String uuid, boolean inTransaction) { + return getLatestResourceByUuid(uuid, false, inTransaction); + } + + public Either<List<Resource>, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean inTransaction) { + return getLatestResourceByUuid(uuid, true, inTransaction); + } + + private Either<List<Resource>, StorageOperationStatus> getLatestResourceByUuid(String uuid, boolean isLatest, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + if (isLatest) { + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isLatest); + } + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + return getResourceListByCriteria(props, inTransaction); + } + + public Either<List<Resource>, StorageOperationStatus> getResourceListBySystemName(String systemName, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + return getResourceListByCriteria(props, inTransaction); + } + + public Either<List<Resource>, StorageOperationStatus> getResourceListByToscaName(String toscaName, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaName); + return getResourceListByCriteria(props, inTransaction); + } + + public Either<List<Resource>, StorageOperationStatus> getResourceByNameAndVersion(String name, String version, boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NAME.getProperty(), name, version, null, inTransaction); + } + + @Override + public Either<List<Resource>, StorageOperationStatus> getResourceByNameAndVersion(String name, String version) { + return getResourceByNameAndVersion(name, version, false); + } + + protected Either<List<Resource>, StorageOperationStatus> getByNamesAndVersion(String nameKey, String nameValue, String version, Map<String, Object> additionalParams, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either<List<ResourceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + List<Resource> resourcesList = new ArrayList<Resource>(); + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List<ResourceMetadataData> dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + // if (dataList.size() > 1) { + // log.debug("More that one instance of resource for name =" + + // nameValue + " and version = " + version); + // return Either.right(StorageOperationStatus.GENERAL_ERROR); + // } + for (ResourceMetadataData resourceData : dataList) { + // ResourceMetadataData resourceData = dataList.get(0); + Either<Resource, StorageOperationStatus> resource = getResource(resourceData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (resource.isRight()) { + log.debug("Failed to fetch resource for name = " + resourceData.getMetadataDataDefinition().getName() + " and id = " + resourceData.getUniqueId()); + return Either.right(resource.right().value()); + } + resourcesList.add(resource.left().value()); + } + // return resource; + return Either.left(resourcesList); + } else { + return Either.right(StorageOperationStatus.NOT_FOUND); + } + } + + @Override + protected <T> Either<T, StorageOperationStatus> getComponentByNameAndVersion(String name, String version, Map<String, Object> additionalParams, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getResourceBySystemNameAndVersion(name, version, additionalParams, inTransaction); + } + + @Override + public Either<Resource, StorageOperationStatus> getResourceBySystemNameAndVersion(String name, String version, Map<String, Object> additionalParams, boolean inTransaction) { + Either<List<Resource>, StorageOperationStatus> byNamesAndVersion = getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), ValidationUtils.normaliseComponentName(name), version, additionalParams, inTransaction); + if (byNamesAndVersion.isRight()) { + return Either.right(byNamesAndVersion.right().value()); + } + List<Resource> resourcesList = byNamesAndVersion.left().value(); + if (resourcesList.size() > 1) { + log.debug("More that one instance of resource for name =" + name + " and version = " + version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(resourcesList.get(0)); + } + + private TitanOperationStatus setAllVersions(Resource resource) { + Either<Map<String, String>, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Resource, resource.getVersion(), resource, ResourceMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + resource.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + @Override + protected <T extends GraphNode> Either<Map<String, String>, TitanOperationStatus> getVersionList(NodeTypeEnum type, String version, Component component, Class<T> clazz) { + Map<String, Object> props = new HashMap<String, Object>(); + Map<String, Object> hasNotProps = new HashMap<String, Object>(); + + if (version.startsWith("0")) { + props.put(GraphPropertiesDictionary.UUID.getProperty(), component.getUUID()); + } else { + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), component.getSystemName()); + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ((Resource) component).getResourceType().name()); + } + hasNotProps.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + Either<List<T>, TitanOperationStatus> result = titanGenericDao.getByCriteria(type, props, hasNotProps, clazz); + + Map<String, String> versionMap = new HashMap<String, String>(); + if (result.isRight()) { + if (!result.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.right(result.right().value()); + } + + } else { + List<ResourceMetadataData> components = (List<ResourceMetadataData>) result.left().value(); + for (ResourceMetadataData data : components) { + versionMap.put(data.getMetadataDataDefinition().getVersion(), (String) data.getUniqueId()); + } + } + + return Either.left(versionMap); + } + + /** + * update only the resource object itself without tag, derived from or any other neighbours. + * + * @param resource + * @param inTransaction + * @return + */ + protected Either<Resource, StorageOperationStatus> updateResourceMetadata(Resource resource, boolean inTransaction) { + + Either<Resource, StorageOperationStatus> result = null; + + try { + + log.debug("In updateResource. received resource = " + (resource == null ? null : resource.toString())); + if (resource == null) { + log.error("Resource object is null"); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + ResourceMetadataData resourceData = new ResourceMetadataData(); + resourceData.getMetadataDataDefinition().setUniqueId(resource.getUniqueId()); + resourceData.getMetadataDataDefinition().setHighestVersion(resource.isHighestVersion()); + log.debug("After converting resource to ResourceData. ResourceData = " + resourceData); + + if (resourceData.getUniqueId() == null) { + log.error("Resource id is missing in the request."); + return Either.right(StorageOperationStatus.BAD_REQUEST); + } + + Either<ResourceMetadataData, TitanOperationStatus> updateNode = titanGenericDao.updateNode(resourceData, ResourceMetadataData.class); + + if (updateNode.isRight()) { + log.error("Failed to update resource " + resource.getUniqueId() + ". status is " + updateNode.right().value()); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(updateNode.right().value())); + return result; + } + + Either<Resource, StorageOperationStatus> updatedResource = getResource(resource.getUniqueId(), true); + if (updatedResource.isRight()) { + log.error("Resource id is missing in the request. status is " + updatedResource.right().value()); + result = Either.right(StorageOperationStatus.BAD_REQUEST); + return result; + } + + Resource updatedResourceValue = updatedResource.left().value(); + result = Either.left(updatedResourceValue); + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Resource retrieved after update is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<List<Resource>, StorageOperationStatus> getAllCertifiedResources(boolean isAbstract, Boolean isHighest) { + + try { + List<Resource> result = new ArrayList<>(); + Map<String, Object> propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.IS_ABSTRACT.getProperty(), isAbstract); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + if (isHighest != null) { + propertiesToMatch.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isHighest.booleanValue()); + } + + Either<List<ResourceMetadataData>, TitanOperationStatus> resourceNodes = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, propertiesToMatch, ResourceMetadataData.class); + + titanGenericDao.commit(); + if (resourceNodes.isRight()) { + // in case of NOT_FOUND from Titan client return to UI empty + // list + if (resourceNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(result); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(resourceNodes.right().value())); + } + } else { + List<ResourceMetadataData> resourceDataList = resourceNodes.left().value(); + for (ResourceMetadataData resourceData : resourceDataList) { + Either<Resource, StorageOperationStatus> resource = getResource(resourceData.getMetadataDataDefinition().getUniqueId()); + if (resource.isRight()) { + log.debug("Failed to fetch resource for id = " + resourceData.getUniqueId() + " error is " + resource.right().value()); + return Either.right(resource.right().value()); + } + result.add(resource.left().value()); + } + return Either.left(result); + } + } finally { + titanGenericDao.commit(); + } + + } + + public Either<Resource, StorageOperationStatus> getLatestCertifiedByToscaResourceName(String toscaResourceName, boolean inTransaction) { + return getLatestCertifiedByCriteria(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), toscaResourceName, inTransaction); + + } + + public Either<Resource, StorageOperationStatus> getLatestCertifiedByCriteria(String property, String resourceName, boolean inTransaction) { + Either<Resource, StorageOperationStatus> result = null; + try { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(property, resourceName); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either<List<ResourceMetadataData>, TitanOperationStatus> highestResources = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestResources.isRight()) { + TitanOperationStatus status = highestResources.right().value(); + log.debug("failed to find resource with name {}. status={} ", resourceName, status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + List<ResourceMetadataData> resources = highestResources.left().value(); + double version = 0.0; + ResourceMetadataData highestResource = null; + for (ResourceMetadataData resource : resources) { + double resourceVersion = Double.parseDouble(resource.getMetadataDataDefinition().getVersion()); + if (resourceVersion > version) { + version = resourceVersion; + highestResource = resource; + } + } + result = getResource(highestResource.getMetadataDataDefinition().getUniqueId(), true); + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.error("getLatestByName operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("getLatestByName operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + + } + } + + public Either<List<Resource>, StorageOperationStatus> findLastCertifiedResourceByName(Resource resource) { + + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), resource.getName()); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + return getResourceListByCriteria(props, false); + + } + + public Either<List<Resource>, StorageOperationStatus> findLastCertifiedResourceByUUID(Resource resource) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.UUID.getProperty(), resource.getUUID()); + props.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + return getResourceListByCriteria(props, false); + + } + + @Override + public boolean isComponentExist(String resourceId) { + return isComponentExist(resourceId, NodeTypeEnum.Resource); + } + + @Override + public <T> Either<T, StorageOperationStatus> cloneComponent(T other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) cloneResource((Resource) other, version, targetLifecycle, inTransaction); + } + + @Override + public Either<Integer, StorageOperationStatus> increaseAndGetComponentInstanceCounter(String componentId, boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Resource, inTransaction); + } + + private Either<Resource, StorageOperationStatus> cloneResource(Resource other, String version, boolean inTransaction) { + return cloneResource(other, version, null, inTransaction); + } + + private Either<Resource, StorageOperationStatus> cloneResource(Resource other, String version, LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either<Resource, StorageOperationStatus> result = null; + + try { + String origRsourceId = other.getUniqueId(); + + StorageOperationStatus overrideStatus = overrideRecursiveMembers(other, origRsourceId); + if (!overrideStatus.equals(StorageOperationStatus.OK)) { + return Either.right(overrideStatus); + } + other.setVersion(version); + other.setUniqueId(null); + + List<InputDefinition> inputs = other.getInputs(); + Map<String, List<ComponentInstanceProperty>> inputsPropMap = new HashMap<String, List<ComponentInstanceProperty>>(); + + if (inputs != null) { + for (InputDefinition input : inputs) { + + Either<List<ComponentInstanceProperty>, TitanOperationStatus> inputPropStatus = inputOperation.getComponentInstancePropertiesByInputId(input.getUniqueId()); + if (inputPropStatus.isLeft()) { + if (inputPropStatus.left().value() != null) + inputsPropMap.put(input.getName(), inputPropStatus.left().value()); + + } + + } + } + + Either<Resource, StorageOperationStatus> createResourceMD = createResource(other, inTransaction); + if (createResourceMD.isRight()) { + StorageOperationStatus status = createResourceMD.right().value(); + log.error("failed to clone resource. status= {}", status); + result = Either.right(status); + return result; + } + Resource resource = createResourceMD.left().value(); + Either<TitanVertex, TitanOperationStatus> metadataVertexEither = titanGenericDao.getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resource.getUniqueId()); + if (metadataVertexEither.isRight()) { + TitanOperationStatus error = metadataVertexEither.right().value(); + log.debug("Failed to fetch vertex of metadata {} error {}", resource.getUniqueId(), error); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(error)); + return result; + } + + TitanVertex metadataVertex = metadataVertexEither.left().value(); + Either<ImmutablePair<List<ComponentInstance>, Map<String, String>>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origRsourceId, resource.getUniqueId(), + NodeTypeEnum.Resource, NodeTypeEnum.Resource, targetLifecycle, metadataVertex, other, resource, inputsPropMap); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either<Integer, StorageOperationStatus> counterStatus = getComponentInstanceCoutner(origRsourceId, NodeTypeEnum.Resource); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on service {}. status={}", origRsourceId, counterStatus); + result = Either.right(status); + return result; + } + + Either<Integer, StorageOperationStatus> setResourceInstanceCounter = setComponentInstanceCounter(resource.getUniqueId(), NodeTypeEnum.Resource, counterStatus.left().value(), true); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on service {}. status={}", resource.getUniqueId(), status); + result = Either.right(status); + return result; + } + + Either<List<GroupDefinition>, StorageOperationStatus> clonedGroups = cloneGroups(other, resource, cloneInstances.left().value(), true); + if (clonedGroups.isRight()) { + StorageOperationStatus status = clonedGroups.right().value(); + if (status != StorageOperationStatus.OK) { + result = Either.right(status); + return result; + } + } + + result = this.getResource(resource.getUniqueId(), true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + // log.debug("Resource retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private StorageOperationStatus overrideRecursiveMembers(Resource resource, String prevId) { + // override requirements to copy only resource's requirements and not + // derived requirements + Either<Map<String, List<RequirementDefinition>>, StorageOperationStatus> requirementsOfResourceOnly = getRequirementOperation().getAllRequirementsOfResourceOnly(prevId, true); + if (requirementsOfResourceOnly.isRight()) { + log.error("failed to get requirements of resource. resourceId {} status is {}", prevId, requirementsOfResourceOnly.right().value()); + return requirementsOfResourceOnly.right().value(); + } + resource.setRequirements(requirementsOfResourceOnly.left().value()); + + // override capabilities to copy only resource's requirements and not + // derived requirements + Either<Map<String, List<CapabilityDefinition>>, StorageOperationStatus> capabilitiesOfResourceOnly = getResourceCapabilitiesMap(prevId); + + resource.setCapabilities(capabilitiesOfResourceOnly.left().value()); + + // override interfaces to copy only resource's interfaces and not + // derived interfaces + Either<Map<String, InterfaceDefinition>, StorageOperationStatus> interfacesOfResourceOnly = getInterfaceLifecycleOperation().getAllInterfacesOfResource(prevId, false, true); + if (interfacesOfResourceOnly.isRight()) { + log.error("failed to get interfaces of resource. resourceId {} status is {}", prevId, interfacesOfResourceOnly.right().value()); + return interfacesOfResourceOnly.right().value(); + } + resource.setInterfaces(interfacesOfResourceOnly.left().value()); + + List<AttributeDefinition> attributes = new ArrayList<>(); + TitanOperationStatus status = attributeOperation.findNodeNonInheretedAttribues(prevId, NodeTypeEnum.Resource, attributes); + if (status != TitanOperationStatus.OK) { + return DaoStatusConverter.convertTitanStatusToStorageStatus(status); + } else { + resource.setAttributes(attributes); + } + + // override properties to copy only resource's properties and not + // derived properties + Either<Map<String, PropertyDefinition>, TitanOperationStatus> propertiesOfResourceOnly = getPropertyOperation().findPropertiesOfNode(NodeTypeEnum.Resource, prevId); + + List<PropertyDefinition> resourceProperties = null; + if (propertiesOfResourceOnly.isRight()) { + TitanOperationStatus titanStatus = propertiesOfResourceOnly.right().value(); + if (titanStatus != TitanOperationStatus.NOT_FOUND) { + log.error("failed to get properties of resource. resourceId {} status is {}", prevId, propertiesOfResourceOnly.right().value()); + return DaoStatusConverter.convertTitanStatusToStorageStatus(titanStatus); + } + } else { + Map<String, PropertyDefinition> propertiesMap = propertiesOfResourceOnly.left().value(); + if (propertiesMap != null) { + resourceProperties = new ArrayList<PropertyDefinition>(); + resourceProperties.addAll(propertiesMap.values()); + } + } + resource.setProperties(resourceProperties); + + return StorageOperationStatus.OK; + } + + private Either<Map<String, List<CapabilityDefinition>>, StorageOperationStatus> getResourceCapabilitiesMap(String prevId) { + + Either<Map<String, CapabilityDefinition>, StorageOperationStatus> capabilitiesOfResourceOnly = getCapabilityOperation().getAllCapabilitiesOfResource(prevId, false, true); + if (capabilitiesOfResourceOnly.isRight()) { + log.error("failed to get capabilities of resource. resourceId {} status is {}", prevId, capabilitiesOfResourceOnly.right().value()); + return Either.right(capabilitiesOfResourceOnly.right().value()); + } + Map<String, List<CapabilityDefinition>> capabilityMap = getCapabilityOperation().convertCapabilityMap(capabilitiesOfResourceOnly.left().value(), null, null); + return Either.left(capabilityMap); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, ComponentMetadataData componentData, NodeTypeEnum type) { + StorageOperationStatus status = StorageOperationStatus.OK; + List<CategoryDefinition> newCategoryList = component.getCategories(); + CategoryDefinition newCategory = newCategoryList.get(0); + CategoryDefinition currentCategory = currentComponent.getCategories().get(0); + boolean categoryWasChanged = false; + + if (newCategory.getName() != null && false == newCategory.getName().equals(currentCategory.getName())) { + // the category was changed + categoryWasChanged = true; + } else { + // the sub-category was changed + SubCategoryDefinition currSubcategory = currentCategory.getSubcategories().get(0); + SubCategoryDefinition newSubcategory = newCategory.getSubcategories().get(0); + if (newSubcategory.getName() != null && false == newSubcategory.getName().equals(currSubcategory.getName())) { + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCategory); + categoryWasChanged = true; + } + } + if (categoryWasChanged) { + status = moveCategoryEdge((Resource) component, (ResourceMetadataData) componentData, newCategory); + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCategory + ". status is " + status); + } + return status; + } + + @Override + public Resource getDefaultComponent() { + return new Resource(); + } + + @Override + public Either<Component, StorageOperationStatus> getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Resource, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertResourceDataToResource((ResourceMetadataData) componentMetadataData); + } + + @Override + public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String componentName) { + return validateComponentNameUniqueness(componentName, titanGenericDao, NodeTypeEnum.Resource); + } + + @Override + public Either<Component, StorageOperationStatus> markComponentToDelete(Component componentToDelete, boolean inTransaction) { + return internalMarkComponentToDelete(componentToDelete, inTransaction); + } + + @Override + public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) { + return isResourceInUse(componentId); + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + return getAllResourcesMarkedForDeletion(); + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllResourcesMarkedForDeletion() { + return getAllComponentsMarkedForDeletion(NodeTypeEnum.Resource); + } + + @Override + public Either<Boolean, StorageOperationStatus> isResourceInUse(String resourceToDelete) { + return isComponentInUse(resourceToDelete, NodeTypeEnum.Resource); + } + + public Either<List<GroupDefinition>, StorageOperationStatus> cloneGroups(Resource resource, Resource newResource, ImmutablePair<List<ComponentInstance>, Map<String, String>> cloneInstances, boolean inTransaction) { + + Either<List<GroupDefinition>, StorageOperationStatus> result = null; + + if (resource.getGroups() == null) { + return Either.right(StorageOperationStatus.OK); + } + + Either<List<GroupDefinition>, StorageOperationStatus> prepareGroupsForCloning = groupOperation.prepareGroupsForCloning(resource, cloneInstances); + if (prepareGroupsForCloning.isRight()) { + StorageOperationStatus status = prepareGroupsForCloning.right().value(); + if (status != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("CloneResource", "Failed to prepare groups for cloning", ErrorSeverity.ERROR); + } + result = Either.right(status); + return result; + } else { + List<GroupDefinition> groupsToCreate = prepareGroupsForCloning.left().value(); + if (groupsToCreate != null && false == groupsToCreate.isEmpty()) { + Either<List<GroupDefinition>, StorageOperationStatus> addGroups = groupOperation.addGroups(NodeTypeEnum.Resource, newResource.getUniqueId(), groupsToCreate, inTransaction); + if (addGroups.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("CloneResource", "Failed to clone groups", ErrorSeverity.ERROR); + result = Either.right(addGroups.right().value()); + return result; + } + + return Either.left(addGroups.left().value()); + } else { + return Either.right(StorageOperationStatus.OK); + } + } + } + + public Either<Resource, StorageOperationStatus> getLatestResourceByCsarOrName(String csarUUID, String systemName) { + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CSAR_UUID.getProperty(), csarUUID); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + ResourceMetadataData resourceMetadataData = null; + List<ResourceMetadataData> resourceMetadataDataList = null; + Either<List<ResourceMetadataData>, TitanOperationStatus> byCsar = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (byCsar.isRight()) { + if (TitanOperationStatus.NOT_FOUND.equals(byCsar.right().value())) { + props.clear(); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + Either<List<ResourceMetadataData>, TitanOperationStatus> bySystemname = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (bySystemname.isRight()) { + log.debug("getLatestResourceByCsarOrName - Failed to find by system name {} error {} ", systemName, bySystemname.right().value()); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(bySystemname.right().value())); + } + if (bySystemname.left().value().size() > 2) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) must return only 2 latest version, but was returned - " + bySystemname.left().value().size()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + resourceMetadataDataList = bySystemname.left().value(); + if (resourceMetadataDataList.size() == 1) { + resourceMetadataData = resourceMetadataDataList.get(0); + } else { + for (ResourceMetadataData curResource : resourceMetadataDataList) { + if (!curResource.getMetadataDataDefinition().getState().equals("CERTIFIED")) { + resourceMetadataData = curResource; + break; + } + } + } + if (resourceMetadataData == null) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by system name) returned 2 latest CERTIFIED versions"); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resourceMetadataData.getMetadataDataDefinition().getCsarUUID() != null && !resourceMetadataData.getMetadataDataDefinition().getCsarUUID().equals(csarUUID)) { + log.debug("getLatestResourceByCsarOrName - same system name {} but different csarUUID. exist {} and new {} ", systemName, resourceMetadataData.getMetadataDataDefinition().getCsarUUID(), csarUUID); + // correct error will be returned from create flow. with all + // correct audit records!!!!! + return Either.right(StorageOperationStatus.NOT_FOUND); + } + Either<Resource, StorageOperationStatus> resource = getResource((String) resourceMetadataData.getUniqueId()); + return resource; + } + } else { + resourceMetadataDataList = byCsar.left().value(); + if (resourceMetadataDataList.size() > 2) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) must return only 2 latest version, but was returned - " + byCsar.left().value().size()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + if (resourceMetadataDataList.size() == 1) { + resourceMetadataData = resourceMetadataDataList.get(0); + } else { + for (ResourceMetadataData curResource : resourceMetadataDataList) { + if (!curResource.getMetadataDataDefinition().getState().equals("CERTIFIED")) { + resourceMetadataData = curResource; + break; + } + } + } + if (resourceMetadataData == null) { + log.debug("getLatestResourceByCsarOrName - getByCriteria(by csar) returned 2 latest CERTIFIED versions"); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Either<Resource, StorageOperationStatus> resource = getResource((String) resourceMetadataData.getMetadataDataDefinition().getUniqueId()); + return resource; + } + return null; + } + + public Either<List<ResourceMetadataData>, StorageOperationStatus> validateCsarUuidUniqueness(String csarUUID) { + + Map<String, Object> props = new HashMap<>(); + props.put(GraphPropertiesDictionary.CSAR_UUID.getProperty(), csarUUID); + + Either<List<ResourceMetadataData>, TitanOperationStatus> byCsar = titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (byCsar.isRight()) { + if (TitanOperationStatus.NOT_FOUND.equals(byCsar.right().value())) { + return Either.left(null); + } else { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCsar.right().value())); + } + } + return Either.left(byCsar.left().value()); + } + + private Either<Resource, StorageOperationStatus> getResource(String uniqueId, ComponentParametersView componentParametersView, boolean inTransaction) { + + Resource resource = null; + try { + + NodeTypeEnum resourceNodeType = NodeTypeEnum.Resource; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + + Either<ResourceMetadataData, StorageOperationStatus> componentByLabelAndId = getComponentByLabelAndId(uniqueId, resourceNodeType, ResourceMetadataData.class); + if (componentByLabelAndId.isRight()) { + return Either.right(componentByLabelAndId.right().value()); + } + ResourceMetadataData resourceData = componentByLabelAndId.left().value(); + + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either<Resource, ActionStatus> componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, resourceData, componentParametersView, Resource.class, ComponentTypeEnum.RESOURCE); + if (componentFromCacheIfUpToDate.isLeft()) { + Resource cachedResource = componentFromCacheIfUpToDate.left().value(); + log.debug("Resource {} with uid {} was fetched from cache.", cachedResource.getName(), cachedResource.getUniqueId()); + return Either.left(cachedResource); + } + + resource = convertResourceDataToResource(resourceData); + + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setResourceCreatorFromGraph(resource, uniqueId); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + status = setResourceLastModifierFromGraph(resource, uniqueId); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreProperties()) { + status = setResourcePropertiesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreAttributesFrom()) { + status = setResourceAttributesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreDerivedFrom()) { + status = setResourceDerivedFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + // Since capabilities and requirements and instances properties are + // based on component instances, then we must fetch the instances. + if (false == componentParametersView.isIgnoreComponentInstances() || false == componentParametersView.isIgnoreComponentInstancesProperties() || false == componentParametersView.isIgnoreComponentInstancesInputs() + || false == componentParametersView.isIgnoreCapabilities() || false == componentParametersView.isIgnoreRequirements()) { + + status = setComponentInstancesFromGraph(uniqueId, resource, resourceNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreRequirements()) { + StorageOperationStatus setRequirementsStatus = setResourceRequirementsFromGraph(uniqueId, resource, true); + if (setRequirementsStatus != StorageOperationStatus.OK) { + log.error("Failed to set requirement of resource " + uniqueId + ". status is " + setRequirementsStatus); + return Either.right(setRequirementsStatus); + } + } + + if (false == componentParametersView.isIgnoreInputs()) { + status = setComponentInputsFromGraph(uniqueId, resource, true); + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource " + uniqueId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + StorageOperationStatus storageStatus = null; + if (false == componentParametersView.isIgnoreCapabilities()) { + storageStatus = setResourceCapabilitiesFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreArtifacts()) { + storageStatus = setArtifactFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + if (false == componentParametersView.isIgnoreComponentInstancesAttributesFrom()) { + status = setComponentInstancesAttributesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreComponentInstancesInputs()) { + status = setComponentInstancesInputsFromGraph(uniqueId, resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + if (false == componentParametersView.isIgnoreInterfaces()) { + storageStatus = setResourceInterfacesFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreAdditionalInformation()) { + storageStatus = setResourceAdditionalInformationFromGraph(uniqueId, resource); + if (storageStatus != StorageOperationStatus.OK) { + return Either.right(storageStatus); + } + } + + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreGroups()) { + status = setGroupsFromGraph(uniqueId, resource, NodeTypeEnum.Resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (true == componentParametersView.isIgnoreComponentInstances()) { + resource.setComponentInstances(null); + resource.setComponentInstancesRelations(null); + } + + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + } + + return Either.left(resource); + + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, ComponentParametersView componentParametersView, boolean inTrasnaction) { + + Either<Resource, StorageOperationStatus> component = getResource(id, componentParametersView, inTrasnaction); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return (Either<T, StorageOperationStatus>) component; + } + + // @Override + public Either<Resource, StorageOperationStatus> updateResource(Resource resource, boolean inTransaction, ComponentParametersView filterResultView) { + return (Either<Resource, StorageOperationStatus>) updateComponentFilterResult(resource, inTransaction, titanGenericDao, resource.getClass(), NodeTypeEnum.Resource, filterResultView); + } + + @Override + protected <T> Either<T, StorageOperationStatus> updateComponentFilterResult(T component, boolean inTransaction, ComponentParametersView filterResultView) { + return (Either<T, StorageOperationStatus>) updateResource((Resource) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java new file mode 100644 index 0000000000..18229f9245 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java @@ -0,0 +1,1566 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.ServiceMetadataDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanGraph; + +import fj.data.Either; + +@org.springframework.stereotype.Component("service-operation") +public class ServiceOperation extends ComponentOperation implements IServiceOperation { + + private static Logger log = LoggerFactory.getLogger(ServiceOperation.class.getName()); + + @Resource + private IArtifactOperation artifactOperation; + + @Resource + private IElementOperation elementOperation; + + public ServiceOperation() { + log.debug("ServiceOperation created"); + } + + @Override + public Either<Service, StorageOperationStatus> createService(Service service) { + return createService(service, false); + } + + @Override + public Either<Service, StorageOperationStatus> createService(Service service, boolean inTransaction) { + Either<Service, StorageOperationStatus> result = null; + + try { + + ServiceMetadataData serviceData = getServiceMetaDataFromService(service); + addComponentInternalFields(serviceData); + String uniqueId = (String) serviceData.getUniqueId(); + generateUUID(service); + + String userId = service.getCreatorUserId(); + + Either<UserData, TitanOperationStatus> findUser = findUser(userId); + + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + + UserData creatorUserData = findUser.left().value(); + UserData updaterUserData = creatorUserData; + String updaterUserId = service.getLastUpdaterUserId(); + if (updaterUserId != null && !updaterUserId.equals(userId)) { + findUser = findUser(updaterUserId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } else { + updaterUserData = findUser.left().value(); + } + } + + // get category + List<CategoryDefinition> categories = service.getCategories(); + CategoryData categoryData = null; + + String categoryName = categories.get(0).getName(); + if (categoryName != null) { + Either<CategoryData, StorageOperationStatus> categoryResult = elementOperation + .getNewCategoryData(categoryName, NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (categoryResult.isRight()) { + StorageOperationStatus status = categoryResult.right().value(); + /* + * TitanOperationStatus titanStatus = null; + * if(ActionStatus.CATEGORY_NOT_FOUND.equals(status)){ + * titanStatus = TitanOperationStatus.NOT_FOUND; }else{ + * titanStatus = TitanOperationStatus.GENERAL_ERROR; } + */ + log.error("Cannot find category " + categoryName + " in the graph. status is " + status); + return Either.right(status); + } + + categoryData = categoryResult.left().value(); + } + + StorageOperationStatus storageOperationStatus = createTagsForComponent(service); + if (storageOperationStatus != StorageOperationStatus.OK) { + return Either.right(storageOperationStatus); + } + + log.debug("try to create service node on graph for id " + serviceData.getUniqueId()); + Either<ServiceMetadataData, TitanOperationStatus> createNode = titanGenericDao.createNode(serviceData, + ServiceMetadataData.class); + if (createNode.isRight()) { + TitanOperationStatus status = createNode.right().value(); + log.error("Error returned after creating service data node " + serviceData + ". status returned is " + + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + log.debug("create service node created on graph for id " + serviceData.getUniqueId()); + + TitanOperationStatus associateMetadata = associateMetadataToComponent(serviceData, creatorUserData, + updaterUserData, null, null); + if (associateMetadata != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateMetadata)); + return result; + } + TitanOperationStatus associateCategory = associateMetadataCategoryToComponent(serviceData, categoryData); + if (associateCategory != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateCategory)); + return result; + } + + Map<String, ArtifactDefinition> allArtifacts = new HashMap<String, ArtifactDefinition>(); + if (service.getArtifacts() != null) { + allArtifacts.putAll(service.getArtifacts()); + } + if (service.getDeploymentArtifacts() != null) { + allArtifacts.putAll(service.getDeploymentArtifacts()); + } + if (service.getServiceApiArtifacts() != null) { + allArtifacts.putAll(service.getServiceApiArtifacts()); + } + if (service.getToscaArtifacts() != null) { + allArtifacts.putAll(service.getToscaArtifacts()); + } + + StorageOperationStatus associateArtifacts = associateArtifactsToComponent(NodeTypeEnum.Service, serviceData, + allArtifacts); + if (associateArtifacts != StorageOperationStatus.OK) { + result = Either.right(associateArtifacts); + return result; + } + + TitanOperationStatus associateInputs = associateInputsToComponent(NodeTypeEnum.Service, serviceData, + service.getInputs()); + if (associateInputs != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(associateInputs)); + return result; + } + + List<AdditionalInformationDefinition> additionalInformation = service.getAdditionalInformation(); + StorageOperationStatus addAdditionalInformation = addAdditionalInformationToService(uniqueId, + additionalInformation); + if (addAdditionalInformation != StorageOperationStatus.OK) { + result = Either.right(addAdditionalInformation); + return result; + } + + result = this.getService(uniqueId, true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isDebugEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.debug("Service retrieved is " + json); + } + + return result; + + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private TitanOperationStatus associateMetadataCategoryToComponent(ServiceMetadataData serviceData, + CategoryData categoryData) { + Either<GraphRelation, TitanOperationStatus> result; + if (categoryData != null) { + result = titanGenericDao.createRelation(serviceData, categoryData, GraphEdgeLabels.CATEGORY, null); + log.debug("After associating component " + serviceData.getUniqueId() + " to category " + categoryData + + ". Edge type is " + GraphEdgeLabels.CATEGORY); + if (result.isRight()) { + log.error("Faield to associate component " + serviceData.getUniqueId() + " to category " + categoryData + + ". Edge type is " + GraphEdgeLabels.CATEGORY); + return result.right().value(); + } + } + return TitanOperationStatus.OK; + } + + private StorageOperationStatus addAdditionalInformationToService(String resourceUniqueId, + List<AdditionalInformationDefinition> additionalInformation) { + + StorageOperationStatus result = null; + + if (additionalInformation == null || true == additionalInformation.isEmpty()) { + result = super.addAdditionalInformation(NodeTypeEnum.Service, resourceUniqueId, null); + } else { + if (additionalInformation.size() == 1) { + result = super.addAdditionalInformation(NodeTypeEnum.Service, resourceUniqueId, + additionalInformation.get(0)); + } else { + result = StorageOperationStatus.BAD_REQUEST; + log.info( + "Cannot create resource with more than one additional information object. The number of received object is " + + additionalInformation.size()); + } + } + return result; + } + + public Either<Service, StorageOperationStatus> cloneService(Service other, String version, boolean inTransaction) { + return cloneService(other, version, null, inTransaction); + } + + public Either<Service, StorageOperationStatus> cloneService(Service other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + Either<Service, StorageOperationStatus> result = null; + + try { + String origServiceId = other.getUniqueId(); + other.setVersion(version); + other.setUniqueId(null); + + Either<Integer, StorageOperationStatus> counterStatus = getComponentInstanceCoutner(origServiceId, + NodeTypeEnum.Service); + if (counterStatus.isRight()) { + StorageOperationStatus status = counterStatus.right().value(); + log.error("failed to get resource instance counter on service {}. status={}", origServiceId, + counterStatus); + result = Either.right(status); + return result; + } + Map<String, List<ComponentInstanceInput>> inputsValuesMap = new HashMap<String, List<ComponentInstanceInput>>(); + List<InputDefinition> inputs = other.getInputs(); + if(inputs != null){ + for(InputDefinition input: inputs){ + + Either<List<ComponentInstanceInput>, TitanOperationStatus> inputStatus = inputOperation.getComponentInstanceInputsByInputId(input.getUniqueId()); + + if(inputStatus.isLeft()){ + if(inputStatus.left().value() != null) + inputsValuesMap.put(input.getName(), inputStatus.left().value()); + } + } + } + + Either<Service, StorageOperationStatus> createServiceMD = createService(other, true); + + if (createServiceMD.isRight()) { + StorageOperationStatus status = createServiceMD.right().value(); + log.error("failed to clone service. status= {}", status); + result = Either.right(status); + return result; + } + + Service service = createServiceMD.left().value(); + + Either<ImmutablePair<List<ComponentInstance>, Map<String, String>>, StorageOperationStatus> cloneInstances = componentInstanceOperation.cloneAllComponentInstancesFromContainerComponent(origServiceId, service, + NodeTypeEnum.Service, NodeTypeEnum.Resource, targetLifecycle, inputsValuesMap); + if (cloneInstances.isRight()) { + result = Either.right(cloneInstances.right().value()); + return result; + } + + Either<Integer, StorageOperationStatus> setResourceInstanceCounter = setComponentInstanceCounter( + service.getUniqueId(), NodeTypeEnum.Service, counterStatus.left().value(), true); + if (setResourceInstanceCounter.isRight()) { + StorageOperationStatus status = setResourceInstanceCounter.right().value(); + log.error("failed to set resource instance counter on service {}. status={}", service.getUniqueId(), + setResourceInstanceCounter); + result = Either.right(status); + return result; + } + + result = this.getService(service.getUniqueId(), true); + if (result.isRight()) { + log.error("Cannot get full service from the graph. status is " + result.right().value()); + return Either.right(result.right().value()); + } + + if (log.isTraceEnabled()) { + String json = prettyJson.toJson(result.left().value()); + log.trace("Resource retrieved is {}", json); + } + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + } + + private ServiceMetadataData getServiceMetaDataFromService(Service service) { + ServiceMetadataData serviceData = new ServiceMetadataData( + (ServiceMetadataDataDefinition) service.getComponentMetadataDefinition().getMetadataDataDefinition()); + if (service.getNormalizedName() == null || service.getNormalizedName().isEmpty()) { + serviceData.getMetadataDataDefinition() + .setNormalizedName(ValidationUtils.normaliseComponentName(service.getName())); + } + if (service.getSystemName() == null || service.getSystemName().isEmpty()) { + serviceData.getMetadataDataDefinition() + .setSystemName(ValidationUtils.convertToSystemName(service.getName())); + } + + return serviceData; + } + + private Either<Service, StorageOperationStatus> sendError(TitanOperationStatus status, + StorageOperationStatus statusIfNotFound) { + Either<Service, StorageOperationStatus> result; + if (status == TitanOperationStatus.NOT_FOUND) { + result = Either.right(statusIfNotFound); + return result; + } else { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + /** + * + */ + public Either<Service, StorageOperationStatus> getService(String uniqueId) { + return getService(uniqueId, false); + } + + public Either<Service, StorageOperationStatus> getService(String uniqueId, boolean inTransaction) { + ComponentParametersView componentParametersView = new ComponentParametersView(); + return getService(uniqueId, componentParametersView, inTransaction); + } + // public Either<Service, StorageOperationStatus> getService(String + // uniqueId, boolean inTransaction) { + // + // Service service = null; + // Either<Service, StorageOperationStatus> result = null; + // try { + // + // NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either<ServiceMetadataData, StorageOperationStatus> getComponentByLabel = + // getComponentByLabelAndId(uniqueId, serviceNodeType, + // ServiceMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // service = convertServiceDataToService(serviceData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(service, + // uniqueId, serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(service, uniqueId, + // serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // // status = setServicePropertiesFromGraph(uniqueId, resource, vertex); + // // if (status != TitanOperationStatus.OK) { + // // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // // } + // + // StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, + // service, serviceNodeType, artifactOperation); + // if (storageStatus != StorageOperationStatus.OK) { + // result = Either.right(storageStatus); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, service, + // serviceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setAllVersions(service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setServiceAdditionalInformationFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setGroupsFromGraph(uniqueId, service, NodeTypeEnum.Resource); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(service); + // return result; + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + public Either<Service, StorageOperationStatus> getService(String uniqueId, + ComponentParametersView componentParametersView, boolean inTransaction) { + + Service service = null; + Either<Service, StorageOperationStatus> result = null; + try { + + NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + + Either<ServiceMetadataData, StorageOperationStatus> getComponentByLabel = getComponentByLabelAndId(uniqueId, + serviceNodeType, ServiceMetadataData.class); + if (getComponentByLabel.isRight()) { + result = Either.right(getComponentByLabel.right().value()); + return result; + } + ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // Try to fetch resource from the cache. The resource will be + // fetched only if the time on the cache equals to + // the time on the graph. + Either<Service, ActionStatus> componentFromCacheIfUpToDate = this.getComponentFromCacheIfUpToDate(uniqueId, + serviceData, componentParametersView, Service.class, ComponentTypeEnum.SERVICE); + if (componentFromCacheIfUpToDate.isLeft()) { + Service cachedService = componentFromCacheIfUpToDate.left().value(); + log.debug("Service {} with uid {} was fetched from cache.", cachedService.getName(), + cachedService.getUniqueId()); + return Either.left(cachedService); + } + + service = convertServiceDataToService(serviceData); + TitanOperationStatus status = null; + if (false == componentParametersView.isIgnoreUsers()) { + status = setComponentCreatorFromGraph(service, uniqueId, serviceNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + status = setComponentLastModifierFromGraph(service, uniqueId, serviceNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreCategories()) { + status = setComponentCategoriesFromGraph(service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + + // status = setServicePropertiesFromGraph(uniqueId, resource, + // vertex); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + + if (false == componentParametersView.isIgnoreArtifacts()) { + StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, service, serviceNodeType, + artifactOperation); + if (storageStatus != StorageOperationStatus.OK) { + result = Either.right(storageStatus); + return result; + } + } + + if (false == componentParametersView.isIgnoreComponentInstances() + || false == componentParametersView.isIgnoreComponentInstancesProperties() + || false == componentParametersView.isIgnoreCapabilities() + || false == componentParametersView.isIgnoreRequirements()) { + status = setComponentInstancesFromGraph(uniqueId, service, serviceNodeType, compInstNodeType); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + + } + } + if (false == componentParametersView.isIgnoreComponentInstancesProperties()) { + status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreCapabilities()) { + status = setCapabilitiesFromGraph(uniqueId, service, NodeTypeEnum.Service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreRequirements()) { + status = setRequirementsFromGraph(uniqueId, service, NodeTypeEnum.Service); + if (status != TitanOperationStatus.OK) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + if (false == componentParametersView.isIgnoreAllVersions()) { + status = setAllVersions(service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + if (false == componentParametersView.isIgnoreAdditionalInformation()) { + status = setServiceAdditionalInformationFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + + if (false == componentParametersView.isIgnoreGroups()) { + status = setGroupsFromGraph(uniqueId, service, NodeTypeEnum.Resource); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + } + if (false == componentParametersView.isIgnoreInputs()) { + status = setComponentInputsFromGraph(uniqueId, service, true); + if (status != TitanOperationStatus.OK) { + log.error("Failed to set inputs of resource " + uniqueId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + } + + if (false == componentParametersView.isIgnoreComponentInstancesInputs()) { + status = setComponentInstancesInputsFromGraph(uniqueId, service); + if (status != TitanOperationStatus.OK) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + + } + } + + result = Either.left(service); + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + + // public Either<Service, StorageOperationStatus> getService_tx(String + // uniqueId, boolean inTransaction) { + // + // Service service = null; + // Either<Service, StorageOperationStatus> result = null; + // try { + // + // NodeTypeEnum serviceNodeType = NodeTypeEnum.Service; + // NodeTypeEnum compInstNodeType = NodeTypeEnum.Resource; + // + // Either<ServiceMetadataData, StorageOperationStatus> getComponentByLabel = + // getComponentByLabelAndId_tx(uniqueId, serviceNodeType, + // ServiceMetadataData.class); + // if (getComponentByLabel.isRight()) { + // result = Either.right(getComponentByLabel.right().value()); + // return result; + // } + // ServiceMetadataData serviceData = getComponentByLabel.left().value(); + // service = convertServiceDataToService(serviceData); + // + // TitanOperationStatus status = setComponentCreatorFromGraph(service, + // uniqueId, serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setComponentLastModifierFromGraph(service, uniqueId, + // serviceNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // status = setComponentCategoriesFromGraph(service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // // status = setServicePropertiesFromGraph(uniqueId, resource, vertex); + // // if (status != TitanOperationStatus.OK) { + // // return + // Either.right(TitanStatusConverter.convertTitanStatusToStorageStatus(status)); + // // } + // + // StorageOperationStatus storageStatus = setArtifactFromGraph(uniqueId, + // service, serviceNodeType, artifactOperation); + // if (storageStatus != StorageOperationStatus.OK) { + // result = Either.right(storageStatus); + // return result; + // } + // + // status = setComponentInstancesFromGraph(uniqueId, service, + // serviceNodeType, compInstNodeType); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // + // } + // + // status = setComponentInstancesPropertiesFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setCapabilitiesFromGraph(uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setRequirementsFromGraph( uniqueId, service, + // NodeTypeEnum.Service); + // if (status != TitanOperationStatus.OK) { + // result = + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // return result; + // } + // + // status = setAllVersions(service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // status = setServiceAdditionalInformationFromGraph(uniqueId, service); + // if (status != TitanOperationStatus.OK) { + // return + // Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + // } + // + // result = Either.left(service); + // return result; + // } finally { + // if (false == inTransaction) { + // if (result == null || result.isRight()) { + // titanGenericDao.rollback(); + // } else { + // titanGenericDao.commit(); + // } + // } + // } + // } + + @Override + TitanOperationStatus setComponentCategoriesFromGraph(Component service) { + + String uniqueId = service.getUniqueId(); + Either<List<ImmutablePair<CategoryData, GraphEdge>>, TitanOperationStatus> parentNode = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), uniqueId, + GraphEdgeLabels.CATEGORY, NodeTypeEnum.ServiceNewCategory, CategoryData.class); + if (parentNode.isRight()) { + return parentNode.right().value(); + } + + List<ImmutablePair<CategoryData, GraphEdge>> listValue = parentNode.left().value(); + if (log.isDebugEnabled()) + log.debug("Result after looking for category nodes pointed by service {}. status is {}", uniqueId, + listValue); + if (listValue.size() > 1) { + log.error("Multiple edges foud between resource " + uniqueId + " to category nodes."); + } + ImmutablePair<CategoryData, GraphEdge> value = listValue.get(0); + if (log.isDebugEnabled()) + log.debug("Found parent node {}", value); + + CategoryData categoryData = value.getKey(); + CategoryDefinition categoryDefinition = new CategoryDefinition(categoryData.getCategoryDataDefinition()); + + List<CategoryDefinition> categories = new ArrayList<>(); + categories.add(categoryDefinition); + service.setCategories(categories); + return TitanOperationStatus.OK; + + } + + @Override + public Either<Service, StorageOperationStatus> deleteService(String serviceId) { + return deleteService(serviceId, false); + } + + @Override + public Either<Service, StorageOperationStatus> deleteService(String serviceId, boolean inTransaction) { + + Either<Service, StorageOperationStatus> result = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + + Either<TitanGraph, TitanOperationStatus> graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + result = Either + .right(DaoStatusConverter.convertTitanStatusToStorageStatus(graphResult.right().value())); + return result; + } + + Either<ServiceMetadataData, TitanOperationStatus> serviceNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), serviceId, ServiceMetadataData.class); + if (serviceNode.isRight()) { + TitanOperationStatus status = serviceNode.right().value(); + log.error("Failed to find service " + serviceId + ". status is " + status); + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + } + + Either<Service, StorageOperationStatus> serviceRes = getService(serviceId, true); + if (serviceRes.isRight()) { + StorageOperationStatus status = serviceRes.right().value(); + log.error("Failed to find sevice " + serviceId + ".status is " + status); + result = Either.right(status); + return result; + } + Service service = serviceRes.left().value(); + + Either<List<ComponentInstance>, StorageOperationStatus> deleteAllResourceInstancesRes = componentInstanceOperation + .deleteAllComponentInstances(serviceId, NodeTypeEnum.Service, true); + log.debug("After deleting resource instances under service " + serviceId + ".Result is " + + deleteAllResourceInstancesRes); + if (deleteAllResourceInstancesRes.isRight()) { + StorageOperationStatus status = deleteAllResourceInstancesRes.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + log.error( + "Failed to delete resource instances under service " + serviceId + " .status is " + status); + result = Either.right(status); + return result; + } + } + StorageOperationStatus removeArtifactsFromResource = removeArtifactsFromComponent(service, + NodeTypeEnum.Service); + log.debug("After deleting artifacts nodes in the graph. status is " + removeArtifactsFromResource); + if (!removeArtifactsFromResource.equals(StorageOperationStatus.OK)) { + result = Either.right(removeArtifactsFromResource); + return result; + } + + StorageOperationStatus removeInputsFromResource = removeInputsFromComponent(NodeTypeEnum.Service, service); + log.debug("After deleting requirements nodes in the graph. status is " + removeInputsFromResource); + if (removeInputsFromResource != StorageOperationStatus.OK) { + result = Either.right(removeInputsFromResource); + return result; + } + + Either<List<ImmutablePair<PropertyData, GraphEdge>>, TitanOperationStatus> deleteChildrenNodesRes = titanGenericDao + .deleteChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), serviceId, + GraphEdgeLabels.PROPERTY, NodeTypeEnum.Property, PropertyData.class); + + if (deleteChildrenNodesRes.isRight()) { + TitanOperationStatus status = deleteChildrenNodesRes.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + } + + StorageOperationStatus removeAdditionalInformationFromService = super.deleteAdditionalInformation( + NodeTypeEnum.Service, serviceId); + log.debug("After deleting additional information node in the graph. status is " + + removeAdditionalInformationFromService); + if (!removeAdditionalInformationFromService.equals(StorageOperationStatus.OK)) { + result = Either.right(removeAdditionalInformationFromService); + return result; + } + + StorageOperationStatus removeGroupsFromService = super.deleteGroups(NodeTypeEnum.Service, serviceId); + log.debug("After deleting group nodes in the graph. status is " + removeGroupsFromService); + if (!removeGroupsFromService.equals(StorageOperationStatus.OK)) { + result = Either.right(removeGroupsFromService); + return result; + } + + Either<ServiceMetadataData, TitanOperationStatus> deleteServiceNodeRes = titanGenericDao + .deleteNode(serviceNode.left().value(), ServiceMetadataData.class); + if (deleteServiceNodeRes.isRight()) { + TitanOperationStatus status = deleteServiceNodeRes.right().value(); + log.error("Failed to delete service node " + serviceId + ". status is " + status); + result = Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(status)); + return result; + } + + result = Either.left(service); + + return result; + } finally { + if (false == inTransaction) { + if (result == null || result.isRight()) { + log.debug("deleteService operation : Going to execute rollback on graph."); + titanGenericDao.rollback(); + } else { + log.debug("deleteService operation : Going to execute commit on graph."); + titanGenericDao.commit(); + } + } + } + + } + + @Override + public Either<Boolean, StorageOperationStatus> validateServiceNameExists(String serviceName) { + return validateServiceNameUniqueness(serviceName, titanGenericDao); + } + + private Service convertServiceDataToService(ServiceMetadataData serviceData) { + ServiceMetadataDefinition serviceMetadataDefinition = new ServiceMetadataDefinition( + (ServiceMetadataDataDefinition) serviceData.getMetadataDataDefinition()); + + Service service = new Service(serviceMetadataDefinition); + + return service; + } + + @Override + public <T extends Component> Either<T, StorageOperationStatus> getComponent(String id, Class<T> clazz) { + + Either<Service, StorageOperationStatus> component = getService(id); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return Either.left(clazz.cast(component.left().value())); + } + + @SuppressWarnings("unchecked") + public Either<List<Service>, StorageOperationStatus> getFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, Set<LifecycleStateEnum> lastStateStates, boolean inTransaction) { + + return (Either<List<Service>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getFollowedComponent( + userId, lifecycleStates, lastStateStates, inTransaction, titanGenericDao, NodeTypeEnum.Service); + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getService(id, inTransaction); + } + + // @Override + // public <T> Either<T, StorageOperationStatus> getComponent_tx(String id, + // boolean inTransaction) { + // return (Either<T, StorageOperationStatus>) getService_tx(id, + // inTransaction); + // } + + @Override + public Either<Set<Service>, StorageOperationStatus> getCatalogData(Map<String, Object> propertiesToMatch, + boolean inTransaction) { + return getComponentCatalogData(NodeTypeEnum.Service, propertiesToMatch, Service.class, + ServiceMetadataData.class, inTransaction); + } + + @Override + public Either<Service, StorageOperationStatus> updateService(Service service, boolean inTransaction) { + Either<Service, StorageOperationStatus> result = updateComponent(service, inTransaction, titanGenericDao, + Service.class, NodeTypeEnum.Service); + return result; + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> updateComponent(T component, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) updateService((Service) component, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either<Component, StorageOperationStatus> deleteComponent(String id, boolean inTransaction) { + return (Either<Component, StorageOperationStatus>) (Either<?, StorageOperationStatus>) deleteService(id, + inTransaction); + } + + @Override + protected ComponentMetadataData getMetaDataFromComponent(Component component) { + return getServiceMetaDataFromService((Service) component); + } + + @Override + public <T> Either<T, StorageOperationStatus> getLightComponent(String id, boolean inTransaction) { + return getLightComponent(id, NodeTypeEnum.Service, inTransaction); + } + + @Override + public <T> Either<List<T>, StorageOperationStatus> getFilteredComponents(Map<FilterKeyEnum, String> filters, + boolean inTransaction) { + Either<List<T>, StorageOperationStatus> components = null; + + String categoryName = filters.get(FilterKeyEnum.CATEGORY); + String distributionStatus = filters.get(FilterKeyEnum.DISTRIBUTION_STATUS); + DistributionStatusEnum distEnum = DistributionStatusEnum.findState(distributionStatus); + if (distributionStatus != null && distEnum == null) { + filters.remove(FilterKeyEnum.CATEGORY); + return Either.right(StorageOperationStatus.CATEGORY_NOT_FOUND); + } + + if (categoryName != null) { // primary filter + components = fetchByCategoryOrSubCategoryName(categoryName, NodeTypeEnum.ServiceNewCategory, + GraphEdgeLabels.CATEGORY.getProperty(), NodeTypeEnum.Service, inTransaction, + ServiceMetadataData.class); + if (components.isLeft() && distEnum != null) {// secondary filter + Predicate<T> statusFilter = p -> ((Service) p).getDistributionStatus().equals(distEnum); + return Either + .left(components.left().value().stream().filter(statusFilter).collect(Collectors.toList())); + } + filters.remove(FilterKeyEnum.DISTRIBUTION_STATUS); + return components; + } + components = fetchByDistributionStatus(distEnum.name(), inTransaction); + if (components.isRight()) { // not found == empty list + return Either.left(new ArrayList<>()); + } + return components; + } + + private <T> Either<List<T>, StorageOperationStatus> fetchByDistributionStatus(String status, + boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + return (Either<List<T>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getServiceListByCriteria( + props, inTransaction); + } + + @SuppressWarnings("unchecked") + @Override + public Either<List<Service>, StorageOperationStatus> getTesterFollowed(String userId, + Set<LifecycleStateEnum> lifecycleStates, boolean inTransaction) { + return (Either<List<Service>, StorageOperationStatus>) (Either<?, StorageOperationStatus>) getTesterFollowedComponent( + userId, lifecycleStates, inTransaction, NodeTypeEnum.Service); + } + + public Either<Service, StorageOperationStatus> updateDestributionStatus(Service service, User user, + DistributionStatusEnum distributionStatus) { + String userId = user.getUserId(); + Either<UserData, TitanOperationStatus> findUser = findUser(userId); + if (findUser.isRight()) { + TitanOperationStatus status = findUser.right().value(); + log.error("Cannot find user " + userId + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.USER_NOT_FOUND); + } + UserData userData = findUser.left().value(); + + Either<ServiceMetadataData, TitanOperationStatus> serviceMetadataDataRequeset = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), service.getUniqueId(), + ServiceMetadataData.class); + if (serviceMetadataDataRequeset.isRight()) { + TitanOperationStatus status = serviceMetadataDataRequeset.right().value(); + log.error("Cannot find service " + service.getUniqueId() + " in the graph. status is " + status); + return sendError(status, StorageOperationStatus.NOT_FOUND); + } + ServiceMetadataData serviceMetadataData = serviceMetadataDataRequeset.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + + Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation = deleteLastDistributionModifierRelation( + service); + if (deleteIncomingRelation.isRight() + && deleteIncomingRelation.right().value() != TitanOperationStatus.NOT_FOUND) { + log.error("Failed to delete user from component " + service.getUniqueId() + ". Edge type is " + + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(deleteIncomingRelation.right().value()); + return Either.right(result); + } + + Either<GraphRelation, TitanOperationStatus> createRelation = titanGenericDao.createRelation(userData, + serviceMetadataData, GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER, null); + log.debug("After associating user " + userData + " to component " + serviceMetadataData.getUniqueId() + + ". Edge type is " + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + if (createRelation.isRight()) { + log.error("Failed to associate user " + userData + " to component " + serviceMetadataData.getUniqueId() + + ". Edge type is " + GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER); + result = DaoStatusConverter.convertTitanStatusToStorageStatus(createRelation.right().value()); + return Either.right(result); + } + service.setDistributionStatus(distributionStatus); + Either<Service, StorageOperationStatus> updateResponse = updateComponent(service, true, titanGenericDao, + Service.class, NodeTypeEnum.Service); + + return updateResponse; + + } + + private Either<GraphRelation, TitanOperationStatus> deleteLastDistributionModifierRelation(Service service) { + GraphRelation lastDistributionStateModifaierRelation = new GraphRelation(); + lastDistributionStateModifaierRelation.setType(GraphEdgeLabels.LAST_DISTRIBUTION_STATE_MODIFAIER.getProperty()); + RelationEndPoint relationEndPoint = new RelationEndPoint(NodeTypeEnum.Service, + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Service), service.getUniqueId()); + lastDistributionStateModifaierRelation.setTo(relationEndPoint); + Either<GraphRelation, TitanOperationStatus> deleteIncomingRelation = titanGenericDao + .deleteIncomingRelation(lastDistributionStateModifaierRelation); + return deleteIncomingRelation; + } + + @Override + public Either<Set<Service>, StorageOperationStatus> getCertifiedServicesWithDistStatus( + Map<String, Object> propertiesToMatch, Set<DistributionStatusEnum> distStatus, boolean inTransaction) { + log.debug("Start getCertifiedServicesWithDistStatus."); + Set<Service> servicesSet = new HashSet<Service>(); + if (distStatus != null && !distStatus.isEmpty()) { + for (DistributionStatusEnum status : distStatus) { + Map<String, Object> props = new HashMap<>(); + props.putAll(propertiesToMatch); + props.put(GraphPropertiesDictionary.DISTRIBUTION_STATUS.getProperty(), status.name()); + Either<Set<Service>, StorageOperationStatus> services = retrieveCertifiedServicesWithStatus( + inTransaction, servicesSet, props); + if (services.isRight()) { + return services; + } else { + servicesSet.addAll(services.left().value()); + } + } + return Either.left(servicesSet); + } else { + return retrieveCertifiedServicesWithStatus(inTransaction, servicesSet, propertiesToMatch); + } + } + + private Either<Set<Service>, StorageOperationStatus> retrieveCertifiedServicesWithStatus(boolean inTransaction, + Set<Service> servicesSet, Map<String, Object> props) { + Either<List<ServiceMetadataData>, TitanOperationStatus> criteriaRes = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + return retrieveComponentsFromNodes(criteriaRes, inTransaction); + } + + public Either<List<Service>, StorageOperationStatus> getServiceCatalogData(boolean inTransaction) { + + long start = System.currentTimeMillis(); + + try { + /* + * Map<String, Object> propertiesToMatch = new HashMap<>(); + * propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty + * (), LifecycleStateEnum.CERTIFIED.name()); + * Either<List<ServiceMetadataData>, TitanOperationStatus> + * lastVersionNodes = getLastVersion(NodeTypeEnum.Service, + * propertiesToMatch, ServiceMetadataData.class); if + * (lastVersionNodes.isRight() && lastVersionNodes.right().value() + * != TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (lastVersionNodes.right().value())); } List<ServiceMetadataData> + * notCertifiedHighest = (lastVersionNodes.isLeft() ? + * lastVersionNodes.left().value() : new + * ArrayList<ServiceMetadataData>()); + * + * propertiesToMatch.put(GraphPropertiesDictionary. + * IS_HIGHEST_VERSION.getProperty(), true); + * Either<List<ServiceMetadataData>, TitanOperationStatus> + * componentsNodes = + * titanGenericDao.getByCriteria(NodeTypeEnum.Service, + * propertiesToMatch, ServiceMetadataData.class); if + * (componentsNodes.isRight() && componentsNodes.right().value() != + * TitanOperationStatus.NOT_FOUND) { return + * Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus + * (componentsNodes.right().value())); } List<ServiceMetadataData> + * certifiedHighest = (componentsNodes.isLeft() ? + * componentsNodes.left().value() : new + * ArrayList<ServiceMetadataData>()); + */ + + Either<List<ServiceMetadataData>, TitanOperationStatus> listOfHighestComponents = this + .getListOfHighestComponents(NodeTypeEnum.Service, ServiceMetadataData.class); + if (listOfHighestComponents.isRight() + && listOfHighestComponents.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right( + DaoStatusConverter.convertTitanStatusToStorageStatus(listOfHighestComponents.right().value())); + } + + List<ServiceMetadataData> notCertifiedHighest = listOfHighestComponents.left().value(); + + List<Service> result = new ArrayList<>(); + + if (notCertifiedHighest != null && false == notCertifiedHighest.isEmpty()) { + + // fetch from cache + long startFetchAllFromCache = System.currentTimeMillis(); + + Map<String, Long> components = notCertifiedHighest.stream() + .collect(Collectors.toMap(p -> p.getMetadataDataDefinition().getUniqueId(), + p -> p.getMetadataDataDefinition().getLastUpdateDate())); + + Either<ImmutablePair<List<Component>, Set<String>>, ActionStatus> componentsFromCacheForCatalog = this + .getComponentsFromCacheForCatalog(components, ComponentTypeEnum.SERVICE); + if (componentsFromCacheForCatalog.isLeft()) { + ImmutablePair<List<Component>, Set<String>> immutablePair = componentsFromCacheForCatalog.left() + .value(); + List<Component> list = immutablePair.getLeft(); + if (list != null) { + for (Component component : list) { + result.add((Service) component); + } + List<String> addedUids = list.stream() + .map(p -> p.getComponentMetadataDefinition().getMetadataDataDefinition().getUniqueId()) + .collect(Collectors.toList()); + notCertifiedHighest = notCertifiedHighest.stream() + .filter(p -> false == addedUids.contains(p.getMetadataDataDefinition().getUniqueId())) + .collect(Collectors.toList()); + } + } + long endFetchAllFromCache = System.currentTimeMillis(); + log.debug("Fetch all catalog services metadata from cache took {} ms", + (endFetchAllFromCache - startFetchAllFromCache)); + log.debug("The number of services added to catalog from cache is {}", result.size()); + + log.debug("The number of services needed to be fetch as light component is {}", + notCertifiedHighest.size()); + for (ServiceMetadataData data : notCertifiedHighest) { + Either<Service, StorageOperationStatus> component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = {}, error : {}. Skip service", data.getUniqueId(), + component.right().value()); + } else { + result.add(component.left().value()); + } + } + } + return Either.left(result); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("Fetch all catalog services took " + (System.currentTimeMillis() - start) + " ms"); + } + + } + + public Either<List<Service>, StorageOperationStatus> getServiceCatalogDataLatestCertifiedAndNotCertified( + boolean inTransaction) { + Map<String, Object> properties = new HashMap<>(); + + properties.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + List<Service> result = new ArrayList<>(); + Either<List<ServiceMetadataData>, TitanOperationStatus> lastVersionNodes = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, properties, ServiceMetadataData.class); + + if (lastVersionNodes.isRight() && lastVersionNodes.right().value() != TitanOperationStatus.NOT_FOUND) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(lastVersionNodes.right().value())); + } + + List<ServiceMetadataData> latestServices; + + if (lastVersionNodes.isLeft()) { + latestServices = lastVersionNodes.left().value(); + } else { + return Either.left(result); + } + + for (ServiceMetadataData data : latestServices) { + Either<Service, StorageOperationStatus> component = getLightComponent( + data.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (component.isRight()) { + log.debug("Failed to get Service for id = " + data.getUniqueId() + " error : " + + component.right().value() + " skip resource"); + } else { + result.add(component.left().value()); + } + } + + return Either.left(result); + + } + + private Either<List<Service>, StorageOperationStatus> getServiceListByCriteria(Map<String, Object> props, + boolean inTransaction) { + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()); + Either<List<ServiceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List<Service> services = new ArrayList<Service>(); + List<ServiceMetadataData> servicesDataList = byCriteria.left().value(); + for (ServiceMetadataData data : servicesDataList) { + Either<Service, StorageOperationStatus> service = getService(data.getMetadataDataDefinition().getUniqueId(), + inTransaction); + if (service.isLeft()) { + services.add(service.left().value()); + } else { + log.debug("Failed to fetch resource for name = " + data.getMetadataDataDefinition().getName() + + " and id = " + data.getUniqueId()); + } + } + return Either.left(services); + } + + public Either<List<Service>, StorageOperationStatus> getServiceListByUuid(String uuid, boolean inTransaction) { + return getLatestServiceByUuid(uuid, false, inTransaction); + } + + public Either<List<Service>, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean inTransaction) { + return getLatestServiceByUuid(uuid, true, inTransaction); + } + + private Either<List<Service>, StorageOperationStatus> getLatestServiceByUuid(String uuid, boolean isLatest, + boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + + if (isLatest) { + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), isLatest); + } + + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid); + return getServiceListByCriteria(props, inTransaction); + } + + public Either<List<Service>, StorageOperationStatus> getServiceListBySystemName(String systemName, + boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + return getServiceListByCriteria(props, inTransaction); + } + + public Either<Service, StorageOperationStatus> getServiceByNameAndVersion(String name, String version, + Map<String, Object> additionalParams, boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.NORMALIZED_NAME.getProperty(), + ValidationUtils.normaliseComponentName(name), version, additionalParams, inTransaction); + } + + @Override + public Either<Service, StorageOperationStatus> getServiceByNameAndVersion(String name, String version) { + return getServiceByNameAndVersion(name, version, null, false); + } + + protected Either<Service, StorageOperationStatus> getByNamesAndVersion(String nameKey, String nameValue, + String version, Map<String, Object> additionalParams, boolean inTransaction) { + Map<String, Object> props = new HashMap<String, Object>(); + props.put(nameKey, nameValue); + props.put(GraphPropertiesDictionary.VERSION.getProperty(), version); + props.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()); + if (additionalParams != null && !additionalParams.isEmpty()) { + props.putAll(additionalParams); + } + + Either<List<ServiceMetadataData>, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + + if (byCriteria.isRight()) { + return Either.right(DaoStatusConverter.convertTitanStatusToStorageStatus(byCriteria.right().value())); + } + List<ServiceMetadataData> dataList = byCriteria.left().value(); + if (dataList != null && !dataList.isEmpty()) { + if (dataList.size() > 1) { + log.debug("More that one instance of resource for name =" + nameValue + " and version = " + version); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + ServiceMetadataData serviceData = dataList.get(0); + Either<Service, StorageOperationStatus> service = getService( + serviceData.getMetadataDataDefinition().getUniqueId(), inTransaction); + if (service.isRight()) { + log.debug("Failed to fetch resource for name = " + serviceData.getMetadataDataDefinition().getName() + + " and id = " + serviceData.getMetadataDataDefinition().getUniqueId()); + } + return service; + } + return Either.right(StorageOperationStatus.NOT_FOUND); + } + + protected <T> Either<T, StorageOperationStatus> getComponentByNameAndVersion(String name, String version, + Map<String, Object> additionalParams, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) getServiceByNameAndVersion(name, version, additionalParams, + inTransaction); + } + + @Override + public Either<Service, StorageOperationStatus> getServiceBySystemNameAndVersion(String name, String version, + boolean inTransaction) { + return getByNamesAndVersion(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), name, version, null, + inTransaction); + } + + private TitanOperationStatus setServiceAdditionalInformationFromGraph(String uniqueId, Service service) { + + List<AdditionalInformationDefinition> additionalInformation = new ArrayList<>(); + + Either<AdditionalInformationDefinition, TitanOperationStatus> either = additionalInformationOperation + .getAllAdditionalInformationParameters(NodeTypeEnum.Service, uniqueId, true); + + if (either.isRight()) { + TitanOperationStatus status = either.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + return TitanOperationStatus.OK; + } + return status; + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + additionalInformation.add(additionalInformationDefinition); + + service.setAdditionalInformation(additionalInformation); + + return TitanOperationStatus.OK; + + } + + private TitanOperationStatus setAllVersions(Service service) { + Either<Map<String, String>, TitanOperationStatus> res = getVersionList(NodeTypeEnum.Service, + service.getVersion(), service, ServiceMetadataData.class); + if (res.isRight()) { + return res.right().value(); + } + service.setAllVersions(res.left().value()); + return TitanOperationStatus.OK; + } + + public Either<List<ArtifactDefinition>, StorageOperationStatus> getAdditionalArtifacts(String resourceId, + boolean recursively, boolean inTransaction) { + List<ArtifactDefinition> artifacts = new ArrayList<>(); + return Either.left(artifacts); + } + + @Override + public boolean isComponentExist(String serviceId) { + return isComponentExist(serviceId, NodeTypeEnum.Service); + } + + // @SuppressWarnings("unchecked") + // @Override + // public <T> Either<T, StorageOperationStatus> cloneComponent(T other, + // String version, boolean inTransaction) { + // return (Either<T, StorageOperationStatus>) cloneService((Service)other, + // version, inTransaction); + // } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> cloneComponent(T other, String version, + LifecycleStateEnum targetLifecycle, boolean inTransaction) { + return (Either<T, StorageOperationStatus>) cloneService((Service) other, version, targetLifecycle, + inTransaction); + } + + @Override + public Either<Integer, StorageOperationStatus> increaseAndGetComponentInstanceCounter(String componentId, + boolean inTransaction) { + return increaseAndGetComponentInstanceCounter(componentId, NodeTypeEnum.Service, inTransaction); + } + + @Override + protected StorageOperationStatus validateCategories(Component currentComponent, Component component, + ComponentMetadataData componentData, NodeTypeEnum type) { + List<CategoryDefinition> newcategories = component.getCategories(); + CategoryDefinition newCat = newcategories.get(0); + CategoryDefinition currentCategory = currentComponent.getCategories().get(0); + + StorageOperationStatus status = StorageOperationStatus.OK; + if (newCat != null && newCat.getName() != null && false == newCat.getName().equals(currentCategory.getName())) { + log.debug( + "Going to update the category of the resource from " + currentCategory + " to " + newCat.getName()); + + status = moveCategoryEdge(component, componentData, newCat, type); + log.debug("Going to update the category of the resource from " + currentCategory + " to " + newCat.getName() + + ". status is " + status); + } + return status; + } + + @Override + protected <T extends Component> StorageOperationStatus updateDerived(Component component, + Component currentComponent, ComponentMetadataData componentData, Class<T> clazz) { + log.debug("Derived class isn't supported for resource"); + return null; + } + + @Override + public Service getDefaultComponent() { + return new Service(); + } + + @Override + public Either<Component, StorageOperationStatus> getMetadataComponent(String id, boolean inTransaction) { + return getMetadataComponent(id, NodeTypeEnum.Service, inTransaction); + } + + @Override + Component convertComponentMetadataDataToComponent(ComponentMetadataData componentMetadataData) { + return convertServiceDataToService((ServiceMetadataData) componentMetadataData); + } + + @Override + public Either<Boolean, StorageOperationStatus> validateComponentNameExists(String componentName) { + return validateComponentNameUniqueness(componentName, titanGenericDao, NodeTypeEnum.Service); + } + + @Override + public Either<Component, StorageOperationStatus> markComponentToDelete(Component componentToDelete, + boolean inTransaction) { + return internalMarkComponentToDelete(componentToDelete, inTransaction); + } + + @Override + public Either<Boolean, StorageOperationStatus> isComponentInUse(String componentId) { + return isComponentInUse(componentId, NodeTypeEnum.Service); + } + + @Override + public Either<List<String>, StorageOperationStatus> getAllComponentsMarkedForDeletion() { + return getAllComponentsMarkedForDeletion(NodeTypeEnum.Service); + } + + @SuppressWarnings("unchecked") + @Override + public <T> Either<T, StorageOperationStatus> getComponent(String id, + ComponentParametersView componentParametersView, boolean inTransaction) { + + Either<Service, StorageOperationStatus> component = getService(id, componentParametersView, inTransaction); + if (component.isRight()) { + return Either.right(component.right().value()); + } + return (Either<T, StorageOperationStatus>) component; + } + + public Either<Service, StorageOperationStatus> updateService(Service service, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either<Service, StorageOperationStatus>) updateComponentFilterResult(service, inTransaction, + titanGenericDao, service.getClass(), NodeTypeEnum.Service, filterResultView); + } + + @Override + protected <T> Either<T, StorageOperationStatus> updateComponentFilterResult(T component, boolean inTransaction, + ComponentParametersView filterResultView) { + return (Either<T, StorageOperationStatus>) updateService((Service) component, inTransaction, filterResultView); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java new file mode 100644 index 0000000000..c4bcf6d907 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java @@ -0,0 +1,244 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.resources.data.ResourceCategoryData; +import org.openecomp.sdc.be.resources.data.ServiceCategoryData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.UserData; + +public class UniqueIdBuilder { + + private static String DOT = "."; + private static final String HEAT_PARAM_PREFIX = "heat_"; + + public static String buildPropertyUniqueId(String resourceId, String propertyName) { + return resourceId + DOT + propertyName; + } + + public static String buildHeatParameterUniqueId(String resourceId, String propertyName) { + return resourceId + DOT + HEAT_PARAM_PREFIX + propertyName; + } + + public static String buildHeatParameterValueUniqueId(String resourceId, String artifactLabel, String propertyName) { + return resourceId + DOT + artifactLabel + DOT + propertyName; + } + + private static UserData userData = new UserData(); + private static TagData tagData = new TagData(); + private static ResourceCategoryData resCategoryData = new ResourceCategoryData(); + private static ServiceCategoryData serCategoryData = new ServiceCategoryData(); + + private static Map<NodeTypeEnum, String> nodeTypeToUniqueKeyMapper = new HashMap<NodeTypeEnum, String>(); + + static { + + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.User, userData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.Tag, tagData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ResourceCategory, resCategoryData.getUniqueIdKey()); + nodeTypeToUniqueKeyMapper.put(NodeTypeEnum.ServiceCategory, serCategoryData.getUniqueIdKey()); + } + + /** + * find the unique id key of a node on the graph + * + * @param nodeTypeEnum + * @return + */ + public static String getKeyByNodeType(NodeTypeEnum nodeTypeEnum) { + + String key = nodeTypeToUniqueKeyMapper.get(nodeTypeEnum); + if (key == null) { + key = GraphPropertiesDictionary.UNIQUE_ID.getProperty(); + } + + return key; + } + + public static String buildResourceUniqueId() { + return generateUUID(); + } + + public static String generateUUID() { + UUID uuid = UUID.randomUUID(); + return uuid.toString(); + } + + public static String buildComponentUniqueId() { + return generateUUID(); + } + + public static String buildConstantProductId() { + return generateUUID(); + } + + public static String buildCapabilityTypeUid(String type) { + return type; + } + + public static String buildAttributeUid(String resourceId, String attName) { + return NodeTypeEnum.Attribute.getName() + DOT + resourceId + DOT + attName; + } + + public static String buildRequirementUid(String resourceId, String reqName) { + return resourceId + DOT + reqName; + } + + public static String buildRequirementImplUid(String resourceId, String reqName) { + + return NodeTypeEnum.RequirementImpl.getName() + DOT + resourceId + DOT + reqName; + + } + + public static String buildCapabilityUid(String resourceId, String capabilityName) { + return NodeTypeEnum.Capability.getName() + DOT + resourceId + DOT + capabilityName; + } + + public static String buildCapabilityInstanceUid(String parentId, String capabilityName) { + return NodeTypeEnum.CapabilityInst.getName() + DOT + parentId + DOT + capabilityName; + } + + public static String buildPropertyValueUniqueId(String parentId, String paramName) { + return NodeTypeEnum.PropertyValue.getName() + DOT + parentId + DOT + paramName; + } + + public static String buildArtifactByInterfaceUniqueId(String resourceId, String interfaceName, String operation, + String artifactLabel) { + + return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel; + } + + // public static String + // buildArtifactByInterfaceUniqueIdAndRsrcNameVersion(String + // resourceName,String resourceVersion,String interfaceName,String + // operation,String artifactLabel) { + // String resourceId = UniqueIdBuilder.buildResourceUniqueId(resourceName, + // resourceVersion); + // return resourceId + DOT + interfaceName + DOT +operation + DOT + + // artifactLabel; + // } + public static String buildArtifactByInterfaceUniqueIdAndRsrcId(String resourceId, String interfaceName, + String operation, String artifactLabel) { + return resourceId + DOT + interfaceName + DOT + operation + DOT + artifactLabel; + } + + public static String buildOperationByInterfaceUniqueId(String resourceId, String interfaceName, String operation) { + + return resourceId + DOT + interfaceName + DOT + operation; + } + + public static String buildInterfaceUniqueId(String resourceId, String interfaceName) { + return resourceId + DOT + interfaceName; + } + + public static String buildResourceInstanceUniuqeId(String serviceId, String resourceId, String logicalName) { + + return serviceId + DOT + resourceId + DOT + logicalName; + } + + public static String buildRelationsipInstInstanceUid(String resourceInstUid, String requirement) { + + return generateUUID(); + } + + /* + * TODO Pavel To be removed when new category logic comes in + */ + public static String buildResourceCategoryUid(String categoryName, String subcategoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName + DOT + subcategoryName; + } + + /* + * TODO Pavel To be removed when new category logic comes in + */ + public static String buildServiceCategoryUid(String categoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName; + } + + // New logic + public static String buildCategoryUid(String categoryName, NodeTypeEnum type) { + return type.getName() + DOT + categoryName; + } + + public static String buildSubCategoryUid(String categoryUid, String subCategoryName) { + return categoryUid + DOT + subCategoryName; + } + + public static String buildGroupingUid(String subCategoryUid, String groupingName) { + return subCategoryUid + DOT + groupingName; + } + + public static String buildResourceInstancePropertyValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "property" + DOT + index; + } + + public static String buildResourceInstanceAttributeValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "attribute" + DOT + index; + } + + public static String buildResourceInstanceInputValueUid(String resourceInstanceUniqueId, Integer index) { + return resourceInstanceUniqueId + DOT + "input" + DOT + index; + } + + public static String buildAdditionalInformationUniqueId(String resourceUniqueId) { + return resourceUniqueId + DOT + "additionalinformation"; + } + + public static String buildHeatParamValueUid(String heatEnvArtifactId, String parameterName) { + return heatEnvArtifactId + DOT + parameterName; + } + + public static String buildDataTypeUid(String name) { + return name + DOT + "datatype"; + } + + public static String buildInvariantUUID() { + return generateUUID(); + } + + public static String buildGroupTypeUid(String type, String version) { + return type + DOT + version + DOT + "grouptype"; + } + + public static String buildPolicyTypeUid(String type, String version) { + return type + DOT + version + DOT + "policytype"; + } + + public static String buildGroupUniqueId(String componentId, String name) { + return componentId + DOT + name + DOT + "group"; + } + + public static String buildGroupPropertyValueUid(String groupUniqueId, Integer index) { + return groupUniqueId + DOT + "property" + DOT + index; + + } + + public static String buildUserFunctionalMenuUid(String userId) { + return userId + DOT + "functionalmenu"; + + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java new file mode 100644 index 0000000000..85bb56f39f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java @@ -0,0 +1,501 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.UserData; +import org.openecomp.sdc.be.resources.data.UserFunctionalMenuData; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +@Component("user-operation") +public class UserAdminOperation implements IUserAdminOperation { + + @javax.annotation.Resource + private TitanGenericDao titanGenericDao; + + public UserAdminOperation() { + super(); + } + + private static Logger log = LoggerFactory.getLogger(UserAdminOperation.class.getName()); + + @Override + public Either<User, ActionStatus> getInactiveUserData(String id) { + return getUserData(id, false, false); + } + + @Override + public Either<User, ActionStatus> getUserData(String id, boolean inTransaction) { + return getUserData(id, true, inTransaction); + } + + private Either<User, ActionStatus> getUserData(String id, boolean isActive, boolean inTransaction) { + log.debug("getUserData - start"); + Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>(); + Wrapper<UserData> userWrapper = new Wrapper<>(); + try { + validateUserExists(resultWrapper, userWrapper, id); + + if (resultWrapper.isEmpty()) { + validateUserData(resultWrapper, userWrapper.getInnerElement(), id); + + } + if (resultWrapper.isEmpty()) { + if (isActive) { + validateActiveUser(resultWrapper, userWrapper.getInnerElement()); + } else { + validateInActiveUser(resultWrapper, userWrapper.getInnerElement()); + } + } + + if (resultWrapper.isEmpty()) { + Either<User, ActionStatus> result = Either.left(convertToUser(userWrapper.getInnerElement())); + resultWrapper.setInnerElement(result); + } + + return resultWrapper.getInnerElement(); + } finally { + if (false == inTransaction) { + titanGenericDao.commit(); + } + log.debug("getUserData - end"); + } + } + + private void validateInActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) { + User user = convertToUser(userData); + if (user.getStatus() == UserStatusEnum.ACTIVE) { + Either<User, ActionStatus> result = Either.right(ActionStatus.USER_NOT_FOUND); + resultWrapper.setInnerElement(result); + } + } + + private void validateActiveUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) { + User user = convertToUser(userData); + if (user.getStatus() == UserStatusEnum.INACTIVE) { + Either<User, ActionStatus> result = Either.right(ActionStatus.USER_INACTIVE); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserData(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData, String id) { + if (userData == null) { + log.debug("Problem get User with userId {}. Reason - either.left().value() = null", id); + Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserExists(Wrapper<Either<User, ActionStatus>> resultWrapper, Wrapper<UserData> userWrapper, + String id) { + Either<User, ActionStatus> result; + if (id == null) { + log.info("User userId is empty"); + result = Either.right(ActionStatus.MISSING_INFORMATION); + resultWrapper.setInnerElement(result); + return; + } + id = id.toLowerCase(); + Either<UserData, TitanOperationStatus> either = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class); + + if (either.isRight()) { + if (either.right().value() == TitanOperationStatus.NOT_FOUND) { + log.debug("User with userId {} not found", id); + result = Either.right(ActionStatus.USER_NOT_FOUND); + resultWrapper.setInnerElement(result); + } else { + log.debug("Problem get User with userId {}. Reason - {}", id, either.right().value().name()); + result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } + } else { + userWrapper.setInnerElement(either.left().value()); + } + } + + @Override + public Either<User, StorageOperationStatus> saveUserData(User user) { + + Either<UserData, TitanOperationStatus> result = null; + try { + UserData userData = convertToUserData(user); + result = titanGenericDao.createNode(userData, UserData.class); + if (result.isRight()) { + log.debug("Problem while saving User {}. Reason - {}", userData.toString(), result.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("User {} saved successfully", userData.toString()); + return Either.left(convertToUser(result.left().value())); + + } finally { + + if (result == null || result.isRight()) { + log.error("saveUserData - Failed"); + titanGenericDao.rollback(); + } else { + log.debug("saveUserData - end"); + titanGenericDao.commit(); + } + } + } + + @Override + public Either<User, StorageOperationStatus> updateUserData(User user) { + Either<UserData, TitanOperationStatus> result = null; + try { + log.debug("updateUserData - start"); + UserData userData = convertToUserData(user); + result = titanGenericDao.updateNode(userData, UserData.class); + if (result.isRight()) { + log.debug("Problem while updating User {}. Reason - {}", userData.toString(), result.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("User {} updated successfully", userData.toString()); + return Either.left(convertToUser(result.left().value())); + + } finally { + + if (result == null || result.isRight()) { + log.error("updateUserData - Failed"); + titanGenericDao.rollback(); + } else { + log.debug("updateUserData - end"); + titanGenericDao.commit(); + } + + } + } + + @Override + public Either<User, StorageOperationStatus> deActivateUser(User user) { + Either<User, StorageOperationStatus> result; + user.setStatus(UserStatusEnum.INACTIVE); + Either<User, StorageOperationStatus> status = updateUserData(user); + if (status.isRight()) { + result = Either.right(status.right().value()); + } else { + result = Either.left(user); + } + return result; + } + + @Override + public Either<User, ActionStatus> deleteUserData(String id) { + Either<User, ActionStatus> result; + Either<UserData, TitanOperationStatus> eitherGet = titanGenericDao + .getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), id, UserData.class); + if (eitherGet.isRight()) { + log.debug("Problem while retriving user with userId {}", id); + if (eitherGet.right().value() == TitanOperationStatus.NOT_FOUND) { + result = Either.right(ActionStatus.USER_NOT_FOUND); + } else { + result = Either.right(ActionStatus.GENERAL_ERROR); + } + + } else { + result = deleteUserLogic(eitherGet.left().value()); + } + return result; + } + + private Either<User, ActionStatus> deleteUserLogic(UserData userData) { + Wrapper<Either<User, ActionStatus>> resultWrapper = new Wrapper<>(); + try { + validateUserHasNoConnections(resultWrapper, userData); + + if (resultWrapper.isEmpty()) { + deleteUser(resultWrapper, userData); + } + + } finally { + titanGenericDao.commit(); + } + + return resultWrapper.getInnerElement(); + } + + private void deleteUser(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) { + Either<UserData, TitanOperationStatus> eitherDelete = titanGenericDao.deleteNode(userData, UserData.class); + if (eitherDelete.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), eitherDelete.right().value().name()); + Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } else { + log.debug("User {} deleted successfully", userData.toString()); + Either<User, ActionStatus> result = Either.left(convertToUser(eitherDelete.left().value())); + resultWrapper.setInnerElement(result); + } + } + + private void validateUserHasNoConnections(Wrapper<Either<User, ActionStatus>> resultWrapper, UserData userData) { + if (resultWrapper.isEmpty()) { + + Either<List<Edge>, TitanOperationStatus> edgesForNode = titanGenericDao.getEdgesForNode(userData, + Direction.BOTH); + if (edgesForNode.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), edgesForNode.right().value().name()); + Either<User, ActionStatus> result = Either.right(ActionStatus.GENERAL_ERROR); + resultWrapper.setInnerElement(result); + } else { + List<Edge> vertexEdges = edgesForNode.left().value(); + if (vertexEdges.size() > 0) { + Either<User, ActionStatus> result = Either.right(ActionStatus.USER_HAS_ACTIVE_ELEMENTS); + resultWrapper.setInnerElement(result); + } + } + } + } + + public Either<List<Edge>, StorageOperationStatus> getUserPandingTasksList(User user, + Map<String, Object> properties) { + + UserData userData = convertToUserData(user); + + Either<TitanVertex, TitanOperationStatus> vertexUser = titanGenericDao + .getVertexByProperty(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.User), user.getUserId()); + if (vertexUser.isRight()) { + log.debug("Problem while deleting User {}. Reason - {}", userData.toString(), vertexUser.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + List<Edge> pandingTasks = new ArrayList<>(); + Either<List<Edge>, TitanOperationStatus> edges = titanGenericDao + .getOutgoingEdgesByCriteria(vertexUser.left().value(), GraphEdgeLabels.STATE, properties); + + if (edges.isRight() || edges.left().value() == null) { + if (edges.right().value() == TitanOperationStatus.NOT_FOUND) { + return Either.left(pandingTasks); + } else { + log.debug("Problem while deleting User {}", userData.toString(), edges.right().value().name()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + + for (Edge edge : edges.left().value()) { + Vertex componentVertex = edge.inVertex(); + VertexProperty<Object> property = componentVertex + .property(GraphPropertiesDictionary.IS_DELETED.getProperty()); + if (!property.isPresent()) { + pandingTasks.add(edge); + } else { + Boolean isDeletedValue = (java.lang.Boolean) property.value(); + if (isDeletedValue == null || isDeletedValue == false) { + pandingTasks.add(edge); + } + } + } + + return Either.left(pandingTasks); + } + + @Override + public Either<List<User>, ActionStatus> getAllUsersWithRole(String role, String status) { + try { + List<User> result = new ArrayList<>(); + Map<String, Object> propertiesToMatch = new HashMap<>(); + if (role != null && !role.trim().isEmpty()) { + propertiesToMatch.put(GraphPropertiesDictionary.ROLE.getProperty(), role); + } + if (status != null && !status.isEmpty()) { + propertiesToMatch.put(GraphPropertiesDictionary.USER_STATUS.getProperty(), status); + } + + Either<List<UserData>, TitanOperationStatus> userNodes = titanGenericDao.getByCriteria(NodeTypeEnum.User, + propertiesToMatch, UserData.class); + + titanGenericDao.commit(); + if (userNodes.isRight()) { + // in case of NOT_FOUND from Titan return empty list + if (userNodes.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + return Either.left(result); + } else { + log.error("Problem while getting all users with role {}. Reason - {}", role, userNodes.right().value().name()); + return Either.right(ActionStatus.GENERAL_ERROR); + } + } else { + List<UserData> userDataList = userNodes.left().value(); + if (userDataList != null) { + for (UserData userData : userDataList) { + User user = convertToUser(userData); + result.add(user); + } + return Either.left(result); + } + log.debug("No users were found with role {}", role); + return Either.left(result); + } + } finally { + titanGenericDao.commit(); + } + } + + protected User convertToUser(UserData userData) { + User user = new User(); + user.setUserId(userData.getUserId()); + user.setEmail(userData.getEmail()); + user.setFirstName(userData.getFirstName()); + user.setLastName(userData.getLastName()); + user.setRole(userData.getRole()); + user.setLastLoginTime(userData.getLastLoginTime()); + // Support backward compatibility - user status may not exist in old + // users + Either<UserStatusEnum, MethodActivationStatusEnum> either = UserStatusEnum.findByName(userData.getStatus()); + user.setStatus(either.isLeft() ? either.left().value() : UserStatusEnum.ACTIVE); + return user; + } + + protected UserData convertToUserData(User user) { + UserData userData = new UserData(); + userData.setUserId(user.getUserId().toLowerCase()); + userData.setEmail(user.getEmail()); + userData.setFirstName(user.getFirstName()); + userData.setLastName(user.getLastName()); + userData.setRole(user.getRole()); + userData.setStatus(user.getStatus().name()); + userData.setLastLoginTime(user.getLastLoginTime()); + return userData; + } + + public Either<ImmutablePair<User, FunctionalMenuInfo>, ActionStatus> getUserDataWithFunctionalMenu(String userId) { + + Either<User, ActionStatus> userData = getUserData(userId, true, true); + + if (userData.isRight()) { + return Either.right(userData.right().value()); + } + User user = userData.left().value(); + Either<UserFunctionalMenuData, TitanOperationStatus> functionalMenu = getFunctionalMenu(userId); + + FunctionalMenuInfo functionalMenuInfo = new FunctionalMenuInfo(); + if (functionalMenu.isRight()) { + TitanOperationStatus status = functionalMenu.right().value(); + if (status != TitanOperationStatus.NOT_FOUND) { + return Either.right(ActionStatus.GENERAL_ERROR); + } + } else { + UserFunctionalMenuData userFunctionalMenuData = functionalMenu.left().value(); + functionalMenuInfo.setFunctionalMenu(userFunctionalMenuData.getFunctionalMenu()); + } + + ImmutablePair<User, FunctionalMenuInfo> result = new ImmutablePair<User, FunctionalMenuInfo>(user, + functionalMenuInfo); + + return Either.left(result); + } + + public Either<UserFunctionalMenuData, TitanOperationStatus> getFunctionalMenu(String userId) { + + Either<UserFunctionalMenuData, TitanOperationStatus> result; + if (userId == null) { + log.info("User userId is empty"); + result = Either.right(TitanOperationStatus.NOT_FOUND); + return result; + } + userId = userId.toLowerCase(); + String uid = UniqueIdBuilder.buildUserFunctionalMenuUid(userId); + + Either<UserFunctionalMenuData, TitanOperationStatus> either = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.UserFunctionalMenu), uid, UserFunctionalMenuData.class); + + return either; + } + + public Either<FunctionalMenuInfo, TitanOperationStatus> createOrUpdateFunctionalMenu(String userId, String newFunctionalMenu) { + + Either<UserFunctionalMenuData, TitanOperationStatus> functionalMenu = getFunctionalMenu(userId); + + if (functionalMenu.isRight()) { + TitanOperationStatus status = functionalMenu.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + String uid = UniqueIdBuilder.buildUserFunctionalMenuUid(userId); + UserFunctionalMenuData functionalMenuData = new UserFunctionalMenuData(newFunctionalMenu, uid); + + Either<UserFunctionalMenuData, TitanOperationStatus> createNode = titanGenericDao + .createNode(functionalMenuData, UserFunctionalMenuData.class); + + if (createNode.isRight()) { + return Either.right(createNode.right().value()); + } else { + return Either.left(convert(createNode.left().value())); + } + + } else { + return Either.right(status); + } + + } else { + UserFunctionalMenuData userFunctionalMenuData = functionalMenu.left().value(); + userFunctionalMenuData.setFunctionalMenu(newFunctionalMenu); + Either<UserFunctionalMenuData, TitanOperationStatus> updateNode = titanGenericDao + .updateNode(userFunctionalMenuData, UserFunctionalMenuData.class); + + if (updateNode.isRight()) { + return Either.right(updateNode.right().value()); + } else { + return Either.left(convert(updateNode.left().value())); + } + } + + } + + private FunctionalMenuInfo convert(UserFunctionalMenuData functionalMenuData) { + + if (functionalMenuData == null) { + return null; + } + + FunctionalMenuInfo functionalMenuInfo = new FunctionalMenuInfo(); + functionalMenuInfo.setFunctionalMenu(functionalMenuData.getFunctionalMenu()); + + return functionalMenuInfo; + + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java new file mode 100644 index 0000000000..fd6563ac4f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.utils; + +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.IComponentOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class ComponentValidationUtils { + + private static Logger log = LoggerFactory.getLogger(ComponentValidationUtils.class.getName()); + + public static boolean canWorkOnResource(Resource resource, String userId) { + // verify resource is checked-out + if (resource.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + log.debug("resource is not checked-out"); + return false; + } + // verify resource is not deleted + if ((resource.getIsDeleted() != null) && (resource.getIsDeleted() == true)) { + log.debug("resource is marked as delete"); + return false; + } + // verify resource last update user is the current user + if (!userId.equals(resource.getLastUpdaterUserId())) { + log.debug("resource last update is not {}", userId); + return false; + } + return true; + } + + public static boolean canWorkOnResource(String resourceId, IResourceOperation resourceOperation, + String userId) { + Either<Resource, StorageOperationStatus> getResourceResult = resourceOperation.getLightComponent(resourceId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrive resource, resource id {}", resourceId); + return false; + } + Resource resource = getResourceResult.left().value(); + + return canWorkOnResource(resource, userId); + + } + + public static boolean canWorkOnService(String serviceId, IServiceOperation serviceOperation, String userId) { + Either<Service, StorageOperationStatus> getResourceResult = serviceOperation.getLightComponent(serviceId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrieve service, service id {}", serviceId); + return false; + } + Service service = getResourceResult.left().value(); + + return canWorkOnComponent(service, userId); + + } + + public static boolean canWorkOnComponent(String componentId, IComponentOperation componentOperation, + String userId) { + Either<Component, StorageOperationStatus> getResourceResult = componentOperation.getLightComponent(componentId, + false); + + if (getResourceResult.isRight()) { + log.debug("Failed to retrieve component, component id {}", componentId); + return false; + } + Component service = getResourceResult.left().value(); + + return canWorkOnComponent(service, userId); + } + + public static boolean canWorkOnComponent(Component component, String userId) { + // verify resource is checked-out + if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + log.debug("resource is not checked-out"); + return false; + } + + // verify userId is not null + if (userId == null) { + log.debug("current user userId is null"); + return false; + } + + // verify resource last update user is the current user + if (!userId.equals(component.getLastUpdaterUserId())) { + log.debug("resource last updater userId is not {}", userId); + return false; + } + return true; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java new file mode 100644 index 0000000000..1d78252de2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.operations.utils; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class GraphDeleteUtil { + + private static Logger log = LoggerFactory.getLogger(GraphDeleteUtil.class.getName()); + + public TitanOperationStatus deleteChildrenNodes(Vertex rootVertex, GraphEdgeLabels edgeType) { + + // Iterable<Edge> edgesCreatorIterable = + // rootVertex.getEdges(Direction.OUT, + // edgeType.name()); + Iterator<Edge> edgesCreatorIterator = rootVertex.edges(Direction.OUT, edgeType.getProperty()); + + while (edgesCreatorIterator.hasNext()) { + Edge edge = edgesCreatorIterator.next(); + Vertex incomingVertex = edge.inVertex(); + Iterator<Edge> outEdges = incomingVertex.edges(Direction.OUT); + + if (outEdges.hasNext()) { + return TitanOperationStatus.CANNOT_DELETE_NON_LEAF_NODE; + } else { + Map<String, Object> properties = null; + if (log.isDebugEnabled()) { + properties = getProperties(incomingVertex); + log.debug("Going to delete vertex {}", properties); + } + incomingVertex.remove(); + if (log.isDebugEnabled()) { + log.debug("After deleting vertex {}", properties); + } + } + + } + + // + // if (edgesCreatorIterable != null) { + // for (Edge edge : edgesCreatorIterable) { + // + // Vertex incomingVertex = edge.getVertex(Direction.IN); + // Iterable<Edge> outEdges = incomingVertex.getEdges(Direction.OUT); + // if (outEdges != null) { + // if (outEdges.iterator().hasNext()) { + // return TitanOperationStatus.CANNOT_DELETE_NON_LEAF_NODE; + // } else { + // Map<String, Object> properties = null; + // if (log.isDebugEnabled()) { + // properties = ElementHelper.getProperties(incomingVertex); + // log.debug("Going to delete vertex {}", properties); + // } + // incomingVertex.remove(); + // if (log.isDebugEnabled()) { + // log.debug("After deleting vertex {}", properties); + // } + // } + // } + // + // } + // } + + return TitanOperationStatus.OK; + + } + + public Map<String, Object> getProperties(Element element) { + + Map<String, Object> result = null; + + if (element.keys() != null && element.keys().size() > 0) { + Map<String, Property> propertyMap = ElementHelper.propertyMap(element, + element.keys().toArray(new String[element.keys().size()])); + result = new HashMap<String, Object>(); + + for (Entry<String, Property> entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java new file mode 100644 index 0000000000..2bbb84dd20 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java @@ -0,0 +1,199 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca; + +import org.openecomp.sdc.be.model.tosca.converters.BooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.DefaultConverter; +import org.openecomp.sdc.be.model.tosca.converters.FloatConverter; +import org.openecomp.sdc.be.model.tosca.converters.IntegerConverter; +import org.openecomp.sdc.be.model.tosca.converters.JsonConverter; +import org.openecomp.sdc.be.model.tosca.converters.ListConverter; +import org.openecomp.sdc.be.model.tosca.converters.MapConverter; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.StringConvertor; +import org.openecomp.sdc.be.model.tosca.converters.ToscaBooleanConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaFloatConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaJsonValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaListValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaStringConvertor; +import org.openecomp.sdc.be.model.tosca.converters.ToscaValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaValueDefaultConverter; +import org.openecomp.sdc.be.model.tosca.validators.BooleanValidator; +import org.openecomp.sdc.be.model.tosca.validators.FloatValidator; +import org.openecomp.sdc.be.model.tosca.validators.IntegerValidator; +import org.openecomp.sdc.be.model.tosca.validators.JsonValidator; +import org.openecomp.sdc.be.model.tosca.validators.KeyValidator; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.be.model.tosca.validators.MapValidator; +import org.openecomp.sdc.be.model.tosca.validators.PropertyTypeValidator; +import org.openecomp.sdc.be.model.tosca.validators.StringValidator; + +/** + * The primitive type that TOSCA YAML supports. + * + * @author esofer + */ +public enum ToscaPropertyType { + + Root("tosca.datatypes.Root", null, null, null, true), + + STRING("string", StringValidator.getInstance(), StringConvertor.getInstance(), ToscaStringConvertor.getInstance()), + + BOOLEAN("boolean", BooleanValidator.getInstance(), ToscaBooleanConverter.getInstance(), + BooleanConverter.getInstance()), + + FLOAT("float", FloatValidator.getInstance(), ToscaFloatConverter.getInstance(), FloatConverter.getInstance()), + + INTEGER("integer", IntegerValidator.getInstance(), DefaultConverter.getInstance(), IntegerConverter.getInstance()), + + SCALAR_UNIT_SIZE("scalar-unit.size", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + SCALAR_UNIT_TIME("scalar-unit.time", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + SCALAR_UNIT_FREQUENCY("scalar-unit.frequency", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + RANGE("range", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + TIMESTAMP("timestamp", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + MAP("map", MapValidator.getInstance(), MapConverter.getInstance(), ToscaMapValueConverter.getInstance()), + + LIST("list", ListValidator.getInstance(), ListConverter.getInstance(), ToscaListValueConverter.getInstance()), + + VERSION("version", StringValidator.getInstance(), DefaultConverter.getInstance(), + ToscaValueDefaultConverter.getInstance()), + + KEY("key", KeyValidator.getInstance(), StringConvertor.getInstance(), ToscaValueDefaultConverter.getInstance()), + + JSON("json", JsonValidator.getInstance(), JsonConverter.getInstance(), ToscaJsonValueConverter.getInstance()); + + // CREDENTIAL("tosca.datatypes.Credential", StringValidator.getInstance(), + // DefaultConverter.getInstance()); + + private String type; + private PropertyTypeValidator validator; + private PropertyValueConverter converter; + private ToscaValueConverter valueConverter; + private boolean isAbstract = false; + + ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, + ToscaValueConverter valueConverter) { + this.type = type; + this.validator = validator; + this.converter = converter; + this.valueConverter = valueConverter; + } + + ToscaPropertyType(String type, PropertyTypeValidator validator, PropertyValueConverter converter, + ToscaValueConverter valueConverter, boolean isAbstract) { + this(type, validator, converter, valueConverter); + this.isAbstract = isAbstract; + } + + // private static final Pattern TIMESTAMP_REGEX = Pattern + // .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[ + // \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([ + // \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?"); + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public PropertyTypeValidator getValidator() { + return validator; + } + + public void setValidator(PropertyTypeValidator validator) { + this.validator = validator; + } + + public PropertyValueConverter getConverter() { + return converter; + } + + public void setConverter(PropertyValueConverter converter) { + this.converter = converter; + } + + public boolean isAbstract() { + return isAbstract; + } + + public void setAbstract(boolean isAbstract) { + this.isAbstract = isAbstract; + } + + public ToscaValueConverter getValueConverter() { + return valueConverter; + } + + public void setValueConverter(ToscaValueConverter valueConverter) { + this.valueConverter = valueConverter; + } + + public static ToscaPropertyType isValidType(String typeName) { + if (typeName == null) { + return null; + } + + for (ToscaPropertyType type : ToscaPropertyType.values()) { + if (type.getType().equals(typeName)) { + return type; + } + } + return null; + } + + public static boolean isScalarType(String dataTypeName) { + + ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName); + + return isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false; + + } + + public static ToscaPropertyType getTypeIfScalar(String dataTypeName) { + + ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName); + + if (isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == false) { + return isPrimitiveToscaType; + } else { + return null; + } + + } + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java new file mode 100644 index 0000000000..88642f8240 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java @@ -0,0 +1,120 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca; + +import java.text.DateFormat; +import java.text.ParseException; +import java.util.Locale; + +/** + * The primitive type that TOSCA YAML supports. + * + * @author mkv + */ +public enum ToscaType { + STRING, INTEGER, FLOAT, BOOLEAN, TIMESTAMP, VERSION; + + // private static final Pattern TIMESTAMP_REGEX = Pattern + // .compile("[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?([Tt]|[ + // \\t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](\\.[0-9]*)?(([ \\t]*)Z|([ + // \\t]*)[-+][0-9][0-9]?(:[0-9][0-9])?)?"); + + public static ToscaType fromYamlTypeName(String typeName) { + if (typeName == null) { + return null; + } + try { + return ToscaType.valueOf(typeName.toUpperCase()); + } catch (IllegalArgumentException e) { + return null; + } + } + + public boolean isValidValue(String value) { + switch (this) { + case BOOLEAN: + return value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false"); + case FLOAT: + return isFloat(value); + case INTEGER: + return isInteger(value); + case STRING: + return true; + case TIMESTAMP: + try { + DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value); + return true; + } catch (ParseException e) { + return false; + } + case VERSION: + return VersionUtil.isValid(value); + default: + return false; + } + } + + private boolean isFloat(String value) { + try { + Float.valueOf(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + private boolean isInteger(String value) { + try { + Long.valueOf(value); + } catch (NumberFormatException e) { + return false; + } + return true; + } + + public Object convert(String value) { + switch (this) { + case STRING: + return value; + case BOOLEAN: + return Boolean.valueOf(value); + case FLOAT: + return Double.valueOf(value); + case INTEGER: + return Long.valueOf(value); + case TIMESTAMP: + try { + return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.US).parse(value); + } catch (ParseException e) { + throw new IllegalArgumentException("Value must be a valid timestamp", e); + } + case VERSION: + return VersionUtil.parseVersion(value); + default: + return null; + } + } + + @Override + public String toString() { + return name().toLowerCase(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java new file mode 100644 index 0000000000..91d806edd9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca; + +import java.util.regex.Pattern; + +import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException; +import org.openecomp.sdc.be.model.tosca.version.Version; + +public final class VersionUtil { + + /** Utility class should not have public constructor. */ + private VersionUtil() { + } + + /** + * The version must begin with a bloc of numbers, and then it can have one + * or more bloc of numbers separated by '.' and then it can have alpha + * numeric bloc separated by '.' or '-' + */ + public static final Pattern VERSION_PATTERN = Pattern.compile("\\d+(?:\\.\\d+)*(?:[\\.-]\\p{Alnum}+)*"); + private static final String SNAPSHOT_IDENTIFIER = "SNAPSHOT"; + + /** + * Check if a version is a SNAPSHOT (development) version. + * + * @param version + * The actual version string. + * @return True if the version is a SNAPSHOT version, false if not (RELEASE + * version). + */ + public static boolean isSnapshot(String version) { + return version.toUpperCase().contains(SNAPSHOT_IDENTIFIER); + } + + /** + * Check if a version is valid + * + * @param version + * version string to parse + * @return true if it's following the defined version pattern + */ + public static boolean isValid(String version) { + return VERSION_PATTERN.matcher(version).matches(); + } + + /** + * Parse the version's text to produce a comparable version object + * + * @param version + * version text to parse + * @return a comparable version object + * @throws ApplicationVersionException + * if the version text is not following the defined version + * pattern + */ + public static Version parseVersion(String version) { + if (!isValid(version)) { + throw new ApplicationVersionException( + "This version is not valid [" + version + "] as it does not match [" + VERSION_PATTERN + "]"); + } else { + return new Version(version); + } + } + + /** + * Compare 2 versions + * + * @param versionLeft + * @param versionRight + * @return + */ + public static int compare(String versionLeft, String versionRight) { + return parseVersion(versionLeft).compareTo(parseVersion(versionRight)); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java new file mode 100644 index 0000000000..7b46692253 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +@SuppressWarnings("rawtypes") +public abstract class AbstractComparablePropertyConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2002627754053326321L; + + private Comparable comparable; + + protected Comparable getComparable() { + return comparable; + } + + protected void initialize(String rawTextValue, ToscaType propertyType) + throws ConstraintValueDoNotMatchPropertyTypeException { + // Perform verification that the property type is supported for + // comparison + ConstraintUtil.checkComparableType(propertyType); + // Check if the text value is valid for the property type + if (propertyType.isValidValue(rawTextValue)) { + // Convert the raw text value to a comparable value + comparable = ConstraintUtil.convertToComparable(propertyType, rawTextValue); + } else { + // Invalid value throw exception + throw new ConstraintValueDoNotMatchPropertyTypeException( + "The value [" + rawTextValue + "] is not valid for the type [" + propertyType + "]"); + } + } + + protected abstract void doValidate(Object propertyValue) throws ConstraintViolationException; + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to check is null"); + } + if (!(comparable.getClass().isAssignableFrom(propertyValue.getClass()))) { + throw new ConstraintViolationException("Value to check is not comparable to reference type, value type [" + + propertyValue.getClass() + "], reference type [" + comparable.getClass() + "]"); + } + doValidate(propertyValue); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java new file mode 100644 index 0000000000..950a7fa9b9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; +import org.openecomp.sdc.be.model.tosca.version.ApplicationVersionException; + +public abstract class AbstractPropertyConstraint implements PropertyConstraint, Serializable { + + /** + * + */ + private static final long serialVersionUID = 4459522275459723374L; + + @Override + public void validate(ToscaType toscaType, String propertyTextValue) throws ConstraintViolationException { + try { + validate(toscaType.convert(propertyTextValue)); + } catch (IllegalArgumentException | ApplicationVersionException e) { + throw new ConstraintViolationException( + "String value [" + propertyTextValue + "] is not valid for type [" + toscaType + "]", e); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java new file mode 100644 index 0000000000..142caa2017 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public abstract class AbstractStringPropertyConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6857605164938136232L; + + protected abstract void doValidate(String propertyValue) throws ConstraintViolationException; + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to validate is null"); + } + if (!(propertyValue instanceof String)) { + throw new ConstraintViolationException("This constraint can only be applied on String value"); + } + doValidate((String) propertyValue); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + ConstraintUtil.checkStringType(propertyType); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java new file mode 100644 index 0000000000..5f19d15293 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.util.Arrays; +import java.util.List; + +public enum ConstraintType { + + IN_RANGE("inRange"), + + GREATER_THAN("greaterThan", "greater_than"), + + GREATER_OR_EQUAL("greaterOrEqual", "greater_or_equal"), + + LESS_OR_EQUAL("lessOrEqual", "less_or_equal"), + + MIN_LENGTH("minLength", "min_length"), + + VALID_VALUES("validValues", "valid_values"), + + LESS_THAN("lessThan", "less_than"); + + List<String> types; + + private ConstraintType(String... types) { + this.types = Arrays.asList(types); + } + + public List<String> getTypes() { + return types; + } + + public static ConstraintType getByType(String type) { + for (ConstraintType inst : ConstraintType.values()) { + if (inst.getTypes().contains(type)) { + return inst; + } + } + return null; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java new file mode 100644 index 0000000000..79ac5caf25 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; + +/** + * Utility class to validate constraints types. + */ +public final class ConstraintUtil { + + private ConstraintUtil() { + } + + /** + * Validates that the {@link ToscaType} specified is a + * {@link ToscaType#STRING}. + * + * @param propertyType + * The property tosca type. + * @throws ConstraintValueDoNotMatchPropertyTypeException + * In case the type is not {@link ToscaType#STRING}. + */ + public static void checkStringType(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + if (!ToscaType.STRING.equals(propertyType)) { + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Invalid property type <" + propertyType.toString() + ">"); + } + } + + /** + * Verify that the given tosca type is supported for comparison + * + * @param propertyType + * the tosca type to check + * @throws ConstraintValueDoNotMatchPropertyTypeException + * if the property type cannot be compared + */ + public static void checkComparableType(ToscaType propertyType) + throws ConstraintValueDoNotMatchPropertyTypeException { + // The validity of the value is already assured by us with our + // ToscaType.convert() method + // here we just want to check that the constraint is not used on + // unsupported type as boolean + switch (propertyType) { + case FLOAT: + case INTEGER: + case TIMESTAMP: + case VERSION: + break; + case STRING: + case BOOLEAN: + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Constraint is invalid for property type <" + propertyType.toString() + ">"); + default: + throw new ConstraintValueDoNotMatchPropertyTypeException( + "Invalid property type <" + propertyType.toString() + ">"); + } + } + + /** + * Convert a string value following its type throw exception if it cannot be + * converted to a comparable + * + * @param propertyType + * the type of the property + * @param value + * the value to convert + * @return the converted comparable + * @throws ConstraintValueDoNotMatchPropertyTypeException + * if the converted value is not a comparable + */ + @SuppressWarnings("rawtypes") + public static Comparable convertToComparable(ToscaType propertyType, String value) + throws ConstraintValueDoNotMatchPropertyTypeException { + Object comparableObj = propertyType.convert(value); + if (!(comparableObj instanceof Comparable)) { + throw new IllegalArgumentException( + "Try to convert a value of a type which is not comparable [" + propertyType + "] to Comparable"); + } else { + return (Comparable) comparableObj; + } + } + + public static class ConstraintInformation { + public ConstraintInformation(String name, Object reference, String value, String type) { + + this.name = name; + this.reference = reference; + this.value = value; + this.type = type; + + } + + private String name; + private Object reference; + private String value; + private String type; + } + + public static ConstraintInformation getConstraintInformation(Object constraint) throws IntrospectionException { + PropertyDescriptor[] propertyDescriptors = Introspector.getBeanInfo(constraint.getClass()) + .getPropertyDescriptors(); + PropertyDescriptor firstDescriptor = null; + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + if (propertyDescriptor.getReadMethod() != null && propertyDescriptor.getWriteMethod() != null) { + firstDescriptor = propertyDescriptor; + break; + } + } + if (firstDescriptor == null) { + throw new IntrospectionException("Cannot find constraint name"); + } + try { + return new ConstraintInformation(firstDescriptor.getName(), + firstDescriptor.getReadMethod().invoke(constraint), null, null); + } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { + throw new IntrospectionException("Cannot retrieve constraint reference " + e.getMessage()); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java new file mode 100644 index 0000000000..530dcb0cc6 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; + +public class EqualConstraint extends AbstractPropertyConstraint implements Serializable { + /** + * + */ + private static final long serialVersionUID = -1596093341744641483L; + + @NotNull + private String equal; + + // @JsonIgnore + private Object typed; + + public EqualConstraint(String equal) { + super(); + this.equal = equal; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + if (propertyType.isValidValue(equal)) { + typed = propertyType.convert(equal); + } else { + throw new ConstraintValueDoNotMatchPropertyTypeException("equal constraint has invalid value <" + equal + + "> property type is <" + propertyType.toString() + ">"); + } + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + if (typed != null) { + fail(null); + } + } else if (typed == null) { + fail(propertyValue); + } else if (!typed.equals(propertyValue)) { + fail(propertyValue); + } + } + + private void fail(Object propertyValue) throws ConstraintViolationException { + throw new ConstraintViolationException("Equal constraint violation, the reference is <" + equal + + "> but the value to compare is <" + propertyValue + ">"); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java new file mode 100644 index 0000000000..4f2c3ad9ca --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class GreaterOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable { + /** + * + */ + private static final long serialVersionUID = -5937851077034490609L; + + @NotNull + private String greaterOrEqual; + + public GreaterOrEqualConstraint(String greaterOrEqual) { + super(); + this.greaterOrEqual = greaterOrEqual; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(greaterOrEqual, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) > 0) { + throw new ConstraintViolationException(propertyValue + " <= " + greaterOrEqual); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java new file mode 100644 index 0000000000..aea2a201ab --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class GreaterThanConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 405723215512121896L; + + public GreaterThanConstraint(String greaterThan) { + super(); + this.greaterThan = greaterThan; + } + + @NotNull + private String greaterThan; + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(greaterThan, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) >= 0) { + throw new ConstraintViolationException(propertyValue + " < " + greaterThan); + } + } + + public String getGreaterThan() { + return greaterThan; + } + + public void setGreaterThan(String greaterThan) { + this.greaterThan = greaterThan; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java new file mode 100644 index 0000000000..e8821c2c21 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; +import java.util.List; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonProperty; +import com.google.common.collect.Lists; + +public class InRangeConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -8038401707152824493L; + + private List<String> inRange; + + private Comparable min; + private Comparable max; + + public InRangeConstraint(List<String> inRange) { + super(); + this.inRange = inRange; + } + + public InRangeConstraint() { + super(); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + // Perform verification that the property type is supported for + // comparison + ConstraintUtil.checkComparableType(propertyType); + if (inRange == null || inRange.size() != 2) { + throw new ConstraintValueDoNotMatchPropertyTypeException("In range constraint must have two elements."); + } + String minRawText = inRange.get(0); + String maxRawText = inRange.get(1); + if (!propertyType.isValidValue(minRawText)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid min value for in range constraint [" + + minRawText + "] as it does not follow the property type [" + propertyType + "]"); + } + if (!propertyType.isValidValue(maxRawText)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("Invalid max value for in range constraint [" + + maxRawText + "] as it does not follow the property type [" + propertyType + "]"); + } + min = ConstraintUtil.convertToComparable(propertyType, minRawText); + max = ConstraintUtil.convertToComparable(propertyType, maxRawText); + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to check is null"); + } + if (!(min.getClass().isAssignableFrom(propertyValue.getClass()))) { + throw new ConstraintViolationException("Value to check is not comparable to range type, value type [" + + propertyValue.getClass() + "], range type [" + min.getClass() + "]"); + } + if (min.compareTo(propertyValue) > 0 || max.compareTo(propertyValue) < 0) { + throw new ConstraintViolationException("The value [" + propertyValue + "] is out of range " + inRange); + } + } + + // @JsonProperty + @NotNull + public String getRangeMinValue() { + if (inRange != null) { + return inRange.get(0); + } else { + return null; + } + } + + // @JsonProperty + public void setRangeMinValue(String minValue) { + if (inRange == null) { + inRange = Lists.newArrayList(minValue, ""); + } else { + inRange.set(0, minValue); + } + } + + // @JsonProperty + @NotNull + public String getRangeMaxValue() { + if (inRange != null) { + return inRange.get(1); + } else { + return null; + } + } + + // @JsonProperty + public void setRangeMaxValue(String maxValue) { + if (inRange == null) { + inRange = Lists.newArrayList("", maxValue); + } else { + inRange.set(1, maxValue); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java new file mode 100644 index 0000000000..2ba0071f2f --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class LengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6249912030281791233L; + + @NotNull + private Integer length; + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() != length) { + throw new ConstraintViolationException("The length of the value is not equals to [" + length + "]"); + } + } + + public Integer getLength() { + return length; + } + + public void setLength(Integer length) { + this.length = length; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java new file mode 100644 index 0000000000..1491fe327d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java @@ -0,0 +1,70 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import alien4cloud.json.deserializer.TextDeserializer; +//import com.fasterxml.jackson.databind.annotation.JsonDeserialize; + +public class LessOrEqualConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = -4907864317687138678L; + + // @JsonDeserialize(using = TextDeserializer.class) + @NotNull + private String lessOrEqual; + + public LessOrEqualConstraint(String lessOrEqual) { + super(); + this.lessOrEqual = lessOrEqual; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(lessOrEqual, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) < 0) { + throw new ConstraintViolationException(propertyValue + " >= " + lessOrEqual); + } + } + + public String getLessOrEqual() { + return lessOrEqual; + } + + public void setLessOrEqual(String lessOrEqual) { + this.lessOrEqual = lessOrEqual; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java new file mode 100644 index 0000000000..2fc43febbf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class LessThanConstraint extends AbstractComparablePropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 2267623014703859501L; + + @NotNull + private String lessThan; + + public LessThanConstraint(String lessThan) { + super(); + this.lessThan = lessThan; + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + initialize(lessThan, propertyType); + } + + @Override + protected void doValidate(Object propertyValue) throws ConstraintViolationException { + if (getComparable().compareTo(propertyValue) <= 0) { + throw new ConstraintViolationException(propertyValue + " > " + lessThan); + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java new file mode 100644 index 0000000000..b6a80afced --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class MaxLengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 6377603705670201256L; + + @NotNull + private Integer maxLength; + + public MaxLengthConstraint(Integer maxLength) { + this.maxLength = maxLength; + } + + public MaxLengthConstraint() { + super(); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() > maxLength) { + throw new ConstraintViolationException("The length of the value is greater than [" + maxLength + "]"); + } + } + + public Integer getMaxLength() { + return maxLength; + } + + public void setMaxLength(Integer maxLength) { + this.maxLength = maxLength; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java new file mode 100644 index 0000000000..f92e5fbb2c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +public class MinLengthConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 32422424680811240L; + + @NotNull + private Integer minLength; + + public MinLengthConstraint(Integer minLength) { + this.minLength = minLength; + } + + public MinLengthConstraint() { + super(); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (propertyValue.length() < minLength) { + throw new ConstraintViolationException("The length of the value is less than [" + minLength + "]"); + } + } + + public Integer getMinLength() { + return minLength; + } + + public void setMinLength(Integer minLength) { + this.minLength = minLength; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java new file mode 100644 index 0000000000..c85c1601e4 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; +import java.util.regex.Pattern; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; + +public class PatternConstraint extends AbstractStringPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 8708185294968697107L; + + @NotNull + private String pattern; + + // @JsonIgnore + private Pattern compiledPattern; + + public void setPattern(String pattern) { + this.pattern = pattern; + this.compiledPattern = Pattern.compile(this.pattern); + } + + @Override + protected void doValidate(String propertyValue) throws ConstraintViolationException { + if (!compiledPattern.matcher(propertyValue).matches()) { + throw new ConstraintViolationException("The value do not match pattern " + pattern); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java new file mode 100644 index 0000000000..738f5150e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +import javax.validation.constraints.NotNull; + +import org.openecomp.sdc.be.model.tosca.ToscaType; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintValueDoNotMatchPropertyTypeException; +import org.openecomp.sdc.be.model.tosca.constraints.exception.ConstraintViolationException; + +//import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.common.collect.Sets; + +public class ValidValuesConstraint extends AbstractPropertyConstraint implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 5906087180079892853L; + + @NotNull + private List<String> validValues; + // @JsonIgnore + private Set<Object> validValuesTyped; + + public ValidValuesConstraint(List<String> validValues) { + super(); + this.validValues = validValues; + } + + public ValidValuesConstraint() { + super(); + } + + @Override + public void initialize(ToscaType propertyType) throws ConstraintValueDoNotMatchPropertyTypeException { + validValuesTyped = Sets.newHashSet(); + if (validValues == null) { + throw new ConstraintValueDoNotMatchPropertyTypeException( + "validValues constraint has invalid value <> property type is <" + propertyType.toString() + ">"); + } + for (String value : validValues) { + if (!propertyType.isValidValue(value)) { + throw new ConstraintValueDoNotMatchPropertyTypeException("validValues constraint has invalid value <" + + value + "> property type is <" + propertyType.toString() + ">"); + } else { + validValuesTyped.add(propertyType.convert(value)); + } + } + } + + @Override + public void validate(Object propertyValue) throws ConstraintViolationException { + if (propertyValue == null) { + throw new ConstraintViolationException("Value to validate is null"); + } + if (!validValuesTyped.contains(propertyValue)) { + throw new ConstraintViolationException("The value is not in the list of valid values"); + } + } + + public List<String> getValidValues() { + return validValues; + } + + public void setValidValues(List<String> validValues) { + this.validValues = validValues; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java new file mode 100644 index 0000000000..3fd165f41e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * All functional error related to constraint processing must go here + * + * @author mkv + * + */ +public class ConstraintFunctionalException extends FunctionalException { + + private static final long serialVersionUID = 1L; + + protected ConstraintInformation constraintInformation; + + public ConstraintFunctionalException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintFunctionalException(String message) { + super(message); + } + + public ConstraintFunctionalException(String message, Throwable cause, ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java new file mode 100644 index 0000000000..2416405de4 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception to be thrown when a required property is not provided + * + * @author mourouvi + * + */ +public class ConstraintRequiredParameterException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 1L; + + public ConstraintRequiredParameterException(String message) { + super(message); + } + + public ConstraintRequiredParameterException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintRequiredParameterException(String message, Throwable cause, + ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java new file mode 100644 index 0000000000..3816ac61dd --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +/** + * Base class for all constraint related exceptions + * + * @author esofer + * + */ +public class ConstraintTechnicalException extends Exception { + + private static final long serialVersionUID = 5829360730980521567L; + + public ConstraintTechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintTechnicalException(String message) { + super(message); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java new file mode 100644 index 0000000000..6ba0d9b864 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception to be thrown when a constraint definition is invalid because the + * specified value doesn't match the property type. + * + * @author esofer + */ +public class ConstraintValueDoNotMatchPropertyTypeException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 4342613849660957651L; + + public ConstraintValueDoNotMatchPropertyTypeException(String message) { + super(message); + } + + public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintValueDoNotMatchPropertyTypeException(String message, Throwable cause, + ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java new file mode 100644 index 0000000000..7fce63841d --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil; +import org.openecomp.sdc.be.model.tosca.constraints.ConstraintUtil.ConstraintInformation; + +/** + * Exception happened while user violated a predefined constraint + * + * @author mkv + * + */ +public class ConstraintViolationException extends ConstraintFunctionalException { + + private static final long serialVersionUID = 1L; + + public ConstraintViolationException(String message) { + super(message); + } + + public ConstraintViolationException(String message, Throwable cause) { + super(message, cause); + } + + public ConstraintViolationException(String message, Throwable cause, ConstraintInformation constraintInformation) { + super(message, cause); + this.constraintInformation = constraintInformation; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java new file mode 100644 index 0000000000..1454306e89 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +/** + * All functional exception which is related to user input must go here. It's a + * checked exception to force error handling and checking. + * + * @author mkv + * + */ +public class FunctionalException extends Exception { + + private static final long serialVersionUID = 6712845685798792493L; + + public FunctionalException(String message, Throwable cause) { + super(message, cause); + } + + public FunctionalException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java new file mode 100644 index 0000000000..2b231d98e3 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +/** + * Exception thrown when the user defines invalid custom property constraint + * + * @author mkv + * + */ +public class InvalidPropertyConstraintImplementationException extends ConstraintTechnicalException { + + private static final long serialVersionUID = 2797550944328544706L; + + public InvalidPropertyConstraintImplementationException(String message, Throwable cause) { + super(message, cause); + } + + public InvalidPropertyConstraintImplementationException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java new file mode 100644 index 0000000000..1bddeea69b --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.constraints.exception; + +/** + * Base class for all Alien technical exception + * + * @author mkv + * + */ +public abstract class TechnicalException extends RuntimeException { + + private static final long serialVersionUID = -9152473183025390161L; + + public TechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public TechnicalException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java new file mode 100644 index 0000000000..f721efb3c9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class BooleanConverter implements ToscaValueConverter { + private static BooleanConverter booleanConverter = new BooleanConverter(); + + public static BooleanConverter getInstance() { + return booleanConverter; + } + + private BooleanConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return Boolean.valueOf(value); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java new file mode 100644 index 0000000000..c190298b52 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class DefaultConverter implements PropertyValueConverter { + + private static DefaultConverter defaultConverter = new DefaultConverter(); + + public static DefaultConverter getInstance() { + return defaultConverter; + } + + private DefaultConverter() { + + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return value; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java new file mode 100644 index 0000000000..d3edd9b8bf --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class FloatConverter implements ToscaValueConverter { + private static FloatConverter floatConverter = new FloatConverter(); + + public static FloatConverter getInstance() { + return floatConverter; + } + + private FloatConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return Double.parseDouble(value); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java new file mode 100644 index 0000000000..147b2e9c52 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatBooleanConverter implements PropertyValueConverter { + + private static HeatBooleanConverter booleanConverter = new HeatBooleanConverter(); + + public static HeatBooleanConverter getInstance() { + return booleanConverter; + } + + private HeatBooleanConverter() { + + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + if (value == null) { + return null; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("t") || value.equalsIgnoreCase("on") + || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("y") || value.equalsIgnoreCase("1")) { + return "true"; + } else { + return "false"; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java new file mode 100644 index 0000000000..a0834791ff --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatCommaDelimitedListConverter implements PropertyValueConverter { + + private static HeatCommaDelimitedListConverter stringConverter = new HeatCommaDelimitedListConverter(); + + public static HeatCommaDelimitedListConverter getInstance() { + return stringConverter; + } + + private HeatCommaDelimitedListConverter() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java new file mode 100644 index 0000000000..6e077d60a1 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatJsonConverter implements PropertyValueConverter { + + private static HeatJsonConverter jsonConverter = new HeatJsonConverter(); + + public static HeatJsonConverter getInstance() { + return jsonConverter; + } + + private HeatJsonConverter() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + // As opposed to string converter, keeping the " and ' symbols + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java new file mode 100644 index 0000000000..90781be367 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.math.BigDecimal; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatNumberConverter implements PropertyValueConverter { + + private static HeatNumberConverter numberConverter = new HeatNumberConverter(); + + public static HeatNumberConverter getInstance() { + return numberConverter; + } + + private HeatNumberConverter() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + if (original == null) { + return null; + } + + return new BigDecimal(original).toPlainString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java new file mode 100644 index 0000000000..475db1db7c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatStringConverter implements PropertyValueConverter { + + private static HeatStringConverter stringConverter = new HeatStringConverter(); + + public static HeatStringConverter getInstance() { + return stringConverter; + } + + private HeatStringConverter() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + coverted = coverted.replaceAll("\"", "").replaceAll("\'", ""); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java new file mode 100644 index 0000000000..076e5aceef --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class IntegerConverter implements ToscaValueConverter { + + private static IntegerConverter integerConverter = new IntegerConverter(); + + public static IntegerConverter getInstance() { + return integerConverter; + } + + private IntegerConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return Integer.parseInt(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java new file mode 100644 index 0000000000..3879430e06 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.GsonFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +public class JsonConverter implements PropertyValueConverter { + + private static JsonConverter jsonConverter = new JsonConverter(); + + private static JsonParser jsonParser = new JsonParser(); + + private static Gson gson = GsonFactory.getGson(); + + public static JsonConverter getInstance() { + return jsonConverter; + } + + private JsonConverter() { + + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + JsonElement jsonElement = jsonParser.parse(jsonReader); + if (jsonElement.isJsonPrimitive()) { + return value; + } + return gson.toJson(jsonElement); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java new file mode 100644 index 0000000000..8265cc2690 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java @@ -0,0 +1,217 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; + +import fj.data.Either; + +public class ListConverter implements PropertyValueConverter { + + private static ListConverter listConverter = new ListConverter(); + private static Gson gson = GsonFactory.getGson(); + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + + DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static ListConverter getInstance() { + return listConverter; + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes); + if (convertWithErrorResult.isRight()) { + return null; + } + + return convertWithErrorResult.left().value(); + } + + public Either<String, Boolean> convertWithErrorResult(String value, String innerType, + Map<String, DataTypeDefinition> dataTypes) { + if (value == null || innerType == null) { + return Either.left(value); + } + + PropertyValueConverter innerConverter; + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + PropertyValueConverter innerConverter1; + switch (innerToscaType) { + case STRING: + innerConverter1 = ToscaPropertyType.STRING.getConverter(); + break; + case INTEGER: + innerConverter1 = ToscaPropertyType.INTEGER.getConverter(); + break; + case FLOAT: + innerConverter1 = ToscaPropertyType.FLOAT.getConverter(); + break; + case BOOLEAN: + innerConverter1 = ToscaPropertyType.BOOLEAN.getConverter(); + break; + case JSON: + innerConverter1 = ToscaPropertyType.JSON.getConverter(); + break; + default: + log.debug("inner Tosca Type is unknown"); + return Either.left(value); + } + innerConverter = innerConverter1; + } else { + log.debug("inner Tosca Type {} ia a complex data type.", innerType); + + Either<String, Boolean> validateComplexInnerType = convertComplexInnerType(value, innerType, dataTypes); + + return validateComplexInnerType; + } + + try { + ArrayList<String> newList = new ArrayList<String>(); + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + String element = JsonUtils.toString(currentValue); + + if (element == null || element.isEmpty()) { + continue; + } + element = innerConverter.convert(element, null, dataTypes); + newList.add(element); + } + + switch (innerToscaType) { + case STRING: + value = gson.toJson(newList); + break; + case INTEGER: + List<BigInteger> intList = new ArrayList<BigInteger>(); + + for (String str : newList) { + int base = 10; + if (str.contains("0x")) { + str = str.replaceFirst("0x", ""); + base = 16; + } + if (str.contains("0o")) { + str = str.replaceFirst("0o", ""); + base = 8; + } + intList.add(new BigInteger(str, base)); + } + value = gson.toJson(intList); + break; + case FLOAT: + value = "["; + for (String str : newList) { + value += str + ","; + } + value = value.substring(0, value.length() - 1); + value += "]"; + break; + case BOOLEAN: + List<Boolean> boolList = new ArrayList<Boolean>(); + for (String str : newList) { + boolList.add(Boolean.valueOf(str)); + } + value = gson.toJson(boolList); + break; + default: + value = gson.toJson(newList); + log.debug("inner Tosca Type unknown : {}", innerToscaType); + } + + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return Either.right(false); + } + + return Either.left(value); + } + + private Either<String, Boolean> convertComplexInnerType(String value, String innerType, + Map<String, DataTypeDefinition> allDataTypes) { + + DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("Cannot find data type {}", innerType); + return Either.right(false); + } + + List<JsonElement> newList = new ArrayList<>(); + + try { + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + + if (currentValue != null) { + + String element = JsonUtils.toString(currentValue); + + ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter + .validateAndUpdate(element, dataTypeDefinition, allDataTypes); + if (validateAndUpdate.right.booleanValue() == false) { + log.debug("Cannot parse value {} from type {} in list position {}", currentValue, innerType, i); + return Either.right(false); + } + JsonElement newValue = validateAndUpdate.left; + newList.add(newValue); + } + } + } catch (Exception e) { + log.debug("Failed to parse the value {} of list parameter.", value); + return Either.right(false); + } + value = gson.toJson(newList); + return Either.left(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java new file mode 100644 index 0000000000..f33be29327 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class LowerCaseConverter implements PropertyValueConverter { + + private static LowerCaseConverter booleanConverter = new LowerCaseConverter(); + + public static LowerCaseConverter getInstance() { + return booleanConverter; + } + + private LowerCaseConverter() { + + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + if (value == null) { + return null; + } + return value.toLowerCase(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java new file mode 100644 index 0000000000..921c6d0d41 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java @@ -0,0 +1,249 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.validators.DataTypeValidatorConverter; +import org.openecomp.sdc.be.model.tosca.validators.ListValidator; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; + +import fj.data.Either; + +public class MapConverter implements PropertyValueConverter { + + private static MapConverter mapConverter = new MapConverter(); + private static Gson gson = GsonFactory.getGson(); + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + + DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static MapConverter getInstance() { + return mapConverter; + } + + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + Either<String, Boolean> convertWithErrorResult = this.convertWithErrorResult(value, innerType, dataTypes); + if (convertWithErrorResult.isRight()) { + return null; + } + + return convertWithErrorResult.left().value(); + } + + public Either<String, Boolean> convertWithErrorResult(String value, String innerType, + Map<String, DataTypeDefinition> dataTypes) { + + if (value == null || value == "" || innerType == null) { + return Either.left(value); + } + + PropertyValueConverter innerConverter; + PropertyValueConverter keyConverter = ToscaPropertyType.STRING.getConverter(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerConverter = ToscaPropertyType.STRING.getConverter(); + break; + case INTEGER: + innerConverter = ToscaPropertyType.INTEGER.getConverter(); + break; + case FLOAT: + innerConverter = ToscaPropertyType.FLOAT.getConverter(); + break; + case BOOLEAN: + innerConverter = ToscaPropertyType.BOOLEAN.getConverter(); + break; + case JSON: + innerConverter = ToscaPropertyType.JSON.getConverter(); + break; + default: + log.debug("inner Tosca Type is unknown"); + return Either.left(value); + } + + } else { + + log.debug("inner Tosca Type {} ia a complex data type.", innerType); + + Either<String, Boolean> validateComplexInnerType = convertComplexInnerType(value, innerType, keyConverter, + dataTypes); + + return validateComplexInnerType; + + } + + try { + Map<String, String> newMap = new HashMap<String, String>(); + + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + for (Entry<String, JsonElement> entry : entrySet) { + String key = entry.getKey(); + JsonElement jsonValue = entry.getValue(); + + key = keyConverter.convert(entry.getKey(), null, dataTypes); + + String element = JsonUtils.toString(jsonValue); + + String val = innerConverter.convert(element, null, dataTypes); + newMap.put(key, val); + } + + String objVal; + switch (innerToscaType) { + case STRING: + value = gson.toJson(newMap); + break; + case INTEGER: + String key = null; + Map<String, Integer> intMap = new HashMap<String, Integer>(); + for (Map.Entry<String, String> entry : newMap.entrySet()) { + objVal = entry.getValue(); + key = entry.getKey(); + if (objVal != null) { + intMap.put(key, Integer.valueOf(objVal.toString())); + } else { + intMap.put(key, null); + } + + } + value = gson.toJson(intMap); + break; + case FLOAT: + value = "{"; + for (Map.Entry<String, String> entry : newMap.entrySet()) { + objVal = entry.getValue(); + if (objVal == null) { + objVal = "null"; + } + key = entry.getKey(); + value += "\"" + key + "\":" + objVal.toString() + ","; + } + value = value.substring(0, value.length() - 1); + value += "}"; + break; + case BOOLEAN: + Map<String, Boolean> boolMap = new HashMap<String, Boolean>(); + for (Map.Entry<String, String> entry : newMap.entrySet()) { + objVal = entry.getValue(); + key = entry.getKey(); + if (objVal != null) { + boolMap.put(key, Boolean.valueOf(objVal.toString())); + } else { + boolMap.put(key, null); + } + } + value = gson.toJson(boolMap); + break; + default: + value = gson.toJson(newMap); + log.debug("inner Tosca Type unknown : {}", innerToscaType); + } + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Converter"); + return Either.right(false); + } + + return Either.left(value); + + } + + /** + * convert the json value of map when the inner type is a complex data type + * + * @param value + * @param innerType + * @param keyConverter + * @param allDataTypes + * @return + */ + private Either<String, Boolean> convertComplexInnerType(String value, String innerType, + PropertyValueConverter keyConverter, Map<String, DataTypeDefinition> allDataTypes) { + + DataTypeDefinition dataTypeDefinition = allDataTypes.get(innerType); + if (dataTypeDefinition == null) { + log.debug("Cannot find data type {}", innerType); + return Either.right(false); + } + + Map<String, JsonElement> newMap = new HashMap<String, JsonElement>(); + + try { + + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + for (Entry<String, JsonElement> entry : entrySet) { + String currentKey = keyConverter.convert(entry.getKey(), null, allDataTypes); + + JsonElement currentValue = entry.getValue(); + + if (currentValue != null) { + + String element = JsonUtils.toString(currentValue); + + ImmutablePair<JsonElement, Boolean> validateAndUpdate = dataTypeValidatorConverter + .validateAndUpdate(element, dataTypeDefinition, allDataTypes); + if (validateAndUpdate.right.booleanValue() == false) { + log.debug("Cannot parse value {} from type {} of key {}", currentValue, innerType, currentKey); + return Either.right(false); + } + JsonElement newValue = validateAndUpdate.left; + newMap.put(currentKey, newValue); + } else { + newMap.put(currentKey, null); + } + } + + } catch (Exception e) { + log.debug("Cannot parse value {} of map from inner type {}", value, innerType); + return Either.right(false); + } + + value = gson.toJson(newMap); + return Either.left(value); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java new file mode 100644 index 0000000000..254785fe8a --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface PropertyValueConverter { + + String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java new file mode 100644 index 0000000000..f5a7ff632e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class StringConvertor implements PropertyValueConverter { + + private static StringConvertor stringConverter = new StringConvertor(); + + public static StringConvertor getInstance() { + return stringConverter; + } + + private StringConvertor() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + if (original == null) { + return null; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(original); + + // coverted = ValidationUtils.convertHtmlTagsToEntities(coverted); + coverted = ValidationUtils.normaliseWhitespace(coverted); + coverted = ValidationUtils.stripOctets(coverted); + coverted = ValidationUtils.removeHtmlTagsOnly(coverted); + + return coverted; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java new file mode 100644 index 0000000000..977415b909 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaBooleanConverter implements PropertyValueConverter { + + private static ToscaBooleanConverter booleanConverter = new ToscaBooleanConverter(); + + public static ToscaBooleanConverter getInstance() { + return booleanConverter; + } + + private ToscaBooleanConverter() { + + } + + @Override + public String convert(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + if (value == null) { + return null; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("yes") + || value.equalsIgnoreCase("y")) { + return "true"; + } else { + return "false"; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java new file mode 100644 index 0000000000..5d7f98e438 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.math.BigDecimal; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaFloatConverter implements PropertyValueConverter { + + private static ToscaFloatConverter numberConverter = new ToscaFloatConverter(); + + public static ToscaFloatConverter getInstance() { + return numberConverter; + } + + private ToscaFloatConverter() { + + } + + @Override + public String convert(String original, String innerType, Map<String, DataTypeDefinition> dataTypes) { + if (original == null) { + return null; + } + if (original.contains("f") || original.contains("F")) + original = original.toLowerCase().replaceFirst("f", ""); + return new BigDecimal(original).toPlainString(); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java new file mode 100644 index 0000000000..d70088e044 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.stream.JsonReader; + +public class ToscaJsonValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaJsonValueConverter toscaJsonConverter = new ToscaJsonValueConverter(); + + public static ToscaJsonValueConverter getInstance() { + return toscaJsonConverter; + } + + private ToscaJsonValueConverter() { + + } + + JsonParser jsonParser = new JsonParser(); + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + JsonElement jsonElement = jsonParser.parse(jsonReader); + if (jsonElement.isJsonPrimitive()) { + return value; + } + return handleComplexJsonValue(jsonElement); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java new file mode 100644 index 0000000000..043446e783 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class ToscaListValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaListValueConverter listConverter = new ToscaListValueConverter(); + private JsonParser jsonParser = new JsonParser(); + private static Logger log = LoggerFactory.getLogger(ToscaListValueConverter.class.getName()); + + public static ToscaListValueConverter getInstance() { + return listConverter; + } + + private ToscaListValueConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + if (value == null) { + return null; + } + try { + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + ToscaValueConverter innerConverter = null; + boolean isScalar = true; + if (innerToscaType != null) { + innerConverter = innerToscaType.getValueConverter(); + } else { + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + + if (dataTypeDefinition != null) { + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) { + innerConverter = toscaPropertyType.getValueConverter(); + } else { + isScalar = false; + innerConverter = ToscaMapValueConverter.getInstance(); + } + } else { + log.debug("inner Tosca Type is null"); + return value; + } + } + JsonElement jsonElement = null; + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + + jsonElement = jsonParser.parse(jsonReader); + } catch (JsonSyntaxException e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + if (jsonElement == null || true == jsonElement.isJsonNull()) { + log.debug("convertToToscaValue json element is null"); + return null; + } + if (jsonElement.isJsonArray() == false) { + // get_input all array like get_input: qrouter_names + return handleComplexJsonValue(jsonElement); + } + JsonArray asJsonArray = jsonElement.getAsJsonArray(); + + ArrayList<Object> toscaList = new ArrayList<Object>(); + final boolean isScalarF = isScalar; + final ToscaValueConverter innerConverterFinal = innerConverter; + asJsonArray.forEach(e -> { + Object convertedValue = null; + if (isScalarF) { + log.debug("try to convert scalar value {}", e.getAsString()); + if (e.getAsString() == null) { + convertedValue = null; + } else { + JsonElement singleElement = jsonParser.parse(e.getAsString()); + if (singleElement.isJsonPrimitive()) { + convertedValue = innerConverterFinal.convertToToscaValue(e.getAsString(), innerType, + dataTypes); + } else { + convertedValue = handleComplexJsonValue(singleElement); + } + } + } else { + JsonObject asJsonObject = e.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition); + Map<String, Object> toscaObjectPresentation = new HashMap<>(); + // log.debug("try to convert datatype value {}", + // e.getAsString()); + + for (Entry<String, JsonElement> entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + continue; + // return null; + } + String type = propertyDefinition.getType(); + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + Object convValue; + if (propertyType != null) { + if (elementValue.isJsonPrimitive()) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, + dataTypes); + } else { + if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + String json = gson.toJson(elementValue); + String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType(); + convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + } else { + String json = gson.toJson(elementValue); + convValue = convertToToscaValue(json, type, dataTypes); + } + toscaObjectPresentation.put(propName, convValue); + } + convertedValue = toscaObjectPresentation; + } + toscaList.add(convertedValue); + }); + return toscaList; + } catch ( + + JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return null; + } + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java new file mode 100644 index 0000000000..601d8f0fc8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class ToscaMapValueConverter extends ToscaValueBaseConverter implements ToscaValueConverter { + private static ToscaMapValueConverter mapConverter = new ToscaMapValueConverter(); + + private JsonParser jsonParser = new JsonParser(); + private static Logger log = LoggerFactory.getLogger(ToscaMapValueConverter.class.getName()); + + public static ToscaMapValueConverter getInstance() { + return mapConverter; + } + + private ToscaMapValueConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + if (value == null) { + return value; + } + try { + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + ToscaValueConverter innerConverter = null; + boolean isScalar = true; + if (innerToscaType != null) { + innerConverter = innerToscaType.getValueConverter(); + } else { + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + if (dataTypeDefinition != null) { + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isScalarType(dataTypeDefinition)) != null) { + innerConverter = toscaPropertyType.getValueConverter(); + } else { + isScalar = false; + } + } else { + // TODO handle getinput + log.debug("inner Tosca Type is null"); + return value; + } + + } + JsonElement jsonElement = null; + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + + jsonElement = jsonParser.parse(jsonReader); + + } catch (JsonSyntaxException e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + if (jsonElement == null || true == jsonElement.isJsonNull()) { + log.debug("convertToToscaValue json element is null"); + return null; + } + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + + Map<String, Object> toscaMap = new HashMap<>(); + final boolean isScalarF = isScalar; + final ToscaValueConverter innerConverterFinal = innerConverter; + entrySet.forEach(e -> { + log.debug("try convert element {}", e.getValue()); + Object convertedValue = convertDataTypeToToscaMap(innerType, dataTypes, innerConverterFinal, isScalarF, + e.getValue()); + toscaMap.put(e.getKey(), convertedValue); + }); + return toscaMap; + } catch (JsonParseException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Converter"); + return null; + } + } + + public Object convertDataTypeToToscaMap(String innerType, Map<String, DataTypeDefinition> dataTypes, + ToscaValueConverter innerConverter, final boolean isScalarF, JsonElement entryValue) { + Object convertedValue = null; + if (isScalarF && entryValue.isJsonPrimitive()) { + log.debug("try convert scalar value {}", entryValue.getAsString()); + if (entryValue.getAsString() == null) { + convertedValue = null; + } else { + convertedValue = innerConverter.convertToToscaValue(entryValue.getAsString(), innerType, dataTypes); + } + } else { + JsonObject asJsonObjectIn = entryValue.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySetIn = asJsonObjectIn.entrySet(); + + DataTypeDefinition dataTypeDefinition = dataTypes.get(innerType); + Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition); + Map<String, Object> toscaObjectPresentation = new HashMap<>(); + + for (Entry<String, JsonElement> entry : entrySetIn) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + Object convValue; + if (isScalarF == false) { + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null && isScalarF) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + continue; + } + + String type = propertyDefinition.getType(); + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType != null) { + if (elementValue.isJsonPrimitive()) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + convValue = valueConverter.convertToToscaValue(elementValue.getAsString(), type, dataTypes); + } else { + if (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(propertyType)) { + ToscaValueConverter valueConverter = propertyType.getValueConverter(); + String json = gson.toJson(elementValue); + String innerTypeRecursive = propertyDefinition.getSchema().getProperty().getType(); + convValue = valueConverter.convertToToscaValue(json, innerTypeRecursive, dataTypes); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + } else { + convValue = convertToToscaValue(elementValue.getAsString(), type, dataTypes); + } + } else { + if (elementValue.isJsonPrimitive()) { + convValue = json2JavaPrimitive(elementValue.getAsJsonPrimitive()); + } else { + convValue = handleComplexJsonValue(elementValue); + } + } + toscaObjectPresentation.put(propName, convValue); + } + convertedValue = toscaObjectPresentation; + } + return convertedValue; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java new file mode 100644 index 0000000000..e228d256c2 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaStringConvertor implements ToscaValueConverter { + private static ToscaStringConvertor stringConverter = new ToscaStringConvertor(); + + public static ToscaStringConvertor getInstance() { + return stringConverter; + } + + private ToscaStringConvertor() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return value; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java new file mode 100644 index 0000000000..e886327481 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java @@ -0,0 +1,153 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; + +public class ToscaValueBaseConverter { + protected Gson gson = new Gson(); + private static Logger log = LoggerFactory.getLogger(ToscaValueBaseConverter.class.getName()); + + protected Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) { + + Map<String, PropertyDefinition> allParentsProps = new HashMap<>(); + + while (dataTypeDefinition != null) { + + List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties(); + if (currentParentsProps != null) { + currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p)); + } + + dataTypeDefinition = dataTypeDefinition.getDerivedFrom(); + } + + return allParentsProps; + } + + public ToscaPropertyType isScalarType(DataTypeDefinition dataTypeDef) { + + ToscaPropertyType result = null; + + DataTypeDefinition dataType = dataTypeDef; + + while (dataType != null) { + + String name = dataType.getName(); + ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name); + if (typeIfScalar != null) { + result = typeIfScalar; + break; + } + + dataType = dataType.getDerivedFrom(); + } + + return result; + } + + public Object handleComplexJsonValue(JsonElement elementValue) { + Object jsonValue = null; + + Map<String, Object> value = new HashMap<String, Object>(); + if ( elementValue.isJsonObject() ){ + JsonObject jsonOb = elementValue.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = jsonOb.entrySet(); + Iterator<Entry<String, JsonElement>> iteratorEntry = entrySet.iterator(); + while (iteratorEntry.hasNext()) { + Entry<String, JsonElement> entry = iteratorEntry.next(); + if (entry.getValue().isJsonArray()) { + List<Object> array = handleJsonArray(entry.getValue()); + value.put(entry.getKey(), array); + } else { + Object object; + if (entry.getValue().isJsonPrimitive()) { + object = json2JavaPrimitive(entry.getValue().getAsJsonPrimitive()); + } else { + object = handleComplexJsonValue(entry.getValue()); + } + value.put(entry.getKey(), object); + } + } + jsonValue = value; + }else{ + if ( elementValue.isJsonArray() ){ + jsonValue = handleJsonArray(elementValue); + }else{ + log.debug("not supported json type {} ",elementValue); + } + } + + return jsonValue; + } + + private List<Object> handleJsonArray(JsonElement entry) { + List<Object> array = new ArrayList<>(); + JsonArray jsonArray = entry.getAsJsonArray(); + Iterator<JsonElement> iterator = jsonArray.iterator(); + while (iterator.hasNext()) { + Object object; + JsonElement element = iterator.next(); + if (element.isJsonPrimitive()) { + object = json2JavaPrimitive(element.getAsJsonPrimitive()); + } else { + object = handleComplexJsonValue(element); + } + array.add(object); + } + return array; + } + + public Object json2JavaPrimitive(JsonPrimitive prim) { + if (prim.isBoolean()) { + return prim.getAsBoolean(); + } else if (prim.isString()) { + return prim.getAsString(); + } else if (prim.isNumber()) { + String strRepesentation = prim.getAsString(); + if (strRepesentation.contains(".")) { + return prim.getAsDouble(); + } else { + return prim.getAsInt(); + } + } else { + throw new IllegalStateException(); + } + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java new file mode 100644 index 0000000000..1b5d4697be --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface ToscaValueConverter { + Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes); + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java new file mode 100644 index 0000000000..b6eb24276e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.converters; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaValueDefaultConverter implements ToscaValueConverter { + private static ToscaValueDefaultConverter deafultConverter = new ToscaValueDefaultConverter(); + + public static ToscaValueDefaultConverter getInstance() { + return deafultConverter; + } + + private ToscaValueDefaultConverter() { + + } + + @Override + public Object convertToToscaValue(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + return value; + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java new file mode 100644 index 0000000000..def0e7c391 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Arrays; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class BooleanValidator implements PropertyTypeValidator { + + private static BooleanValidator booleanValidator = new BooleanValidator(); + private static String[] validValues = { "true", "t", "on", "yes", "y", "1", "false", "f", "off", "no", "n", "0" }; + + public static BooleanValidator getInstance() { + return booleanValidator; + } + + private BooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, null, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java new file mode 100644 index 0000000000..d376a1ec13 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java @@ -0,0 +1,499 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSyntaxException; + +public class DataTypeValidatorConverter { + + private static DataTypeValidatorConverter dataTypeValidatorConverter = new DataTypeValidatorConverter(); + + public static DataTypeValidatorConverter getInstance() { + return dataTypeValidatorConverter; + } + + private DataTypeValidatorConverter() { + + } + + private static Logger log = LoggerFactory.getLogger(DataTypeValidatorConverter.class.getName()); + + JsonParser jsonParser = new JsonParser(); + + Gson gson = new Gson(); + + ImmutablePair<JsonElement, Boolean> falseResult = new ImmutablePair<JsonElement, Boolean>(null, false); + ImmutablePair<JsonElement, Boolean> trueEmptyResult = new ImmutablePair<JsonElement, Boolean>(null, true); + + ImmutablePair<String, Boolean> trueStringEmptyResult = new ImmutablePair<String, Boolean>(null, true); + ImmutablePair<String, Boolean> falseStringEmptyResult = new ImmutablePair<String, Boolean>(null, true); + + private ToscaPropertyType isDataTypeDerviedFromScalarType(DataTypeDefinition dataTypeDef) { + + ToscaPropertyType result = null; + + DataTypeDefinition dataType = dataTypeDef; + + while (dataType != null) { + + String name = dataType.getName(); + ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(name); + if (typeIfScalar != null) { + result = typeIfScalar; + break; + } + + dataType = dataType.getDerivedFrom(); + } + + return result; + } + + private ImmutablePair<JsonElement, Boolean> validateAndUpdate(JsonElement jsonElement, + DataTypeDefinition dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) { + + Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition); + + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) { + + PropertyTypeValidator validator = toscaPropertyType.getValidator(); + PropertyValueConverter converter = toscaPropertyType.getConverter(); + if (jsonElement == null || true == jsonElement.isJsonNull()) { + boolean valid = validator.isValid(null, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}", dataTypeDefinition.getName(), dataTypeDefinition.getName()); + return falseResult; + } + return new ImmutablePair<JsonElement, Boolean>(jsonElement, true); + + } else { + if (true == jsonElement.isJsonPrimitive()) { + String value = null; + if (jsonElement != null) { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + boolean valid = validator.isValid(value, null, null); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value); + return falseResult; + } + + String convertedValue = converter.convert(value, null, allDataTypes); + JsonElement element = null; + try { + element = jsonParser.parse(convertedValue); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse value {} of property {}. {}", convertedValue, dataTypeDefinition.getName(), e); + return falseResult; + } + + return new ImmutablePair<JsonElement, Boolean>(element, true); + + } else { + // MAP, LIST, OTHER types cannot be applied data type + // definition scalar type. We currently cannot derived from + // map/list. (cannot add the entry schema to it) + log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName()); + + return falseResult; + } + } + } else { + + if (jsonElement == null || jsonElement.isJsonNull()) { + + return new ImmutablePair<JsonElement, Boolean>(jsonElement, true); + + } else { + + if (jsonElement.isJsonObject()) { + + JsonObject buildJsonObject = new JsonObject(); + + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + + for (Entry<String, JsonElement> entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data type {}", propName, dataTypeDefinition.getName()); + return falseResult; + } + String type = propertyDefinition.getType(); + boolean isScalarType = ToscaPropertyType.isScalarType(type); + + if (true == isScalarType) { + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType == null) { + log.debug("cannot find the {} under default tosca property types", type); + return falseResult; + } + PropertyTypeValidator validator = propertyType.getValidator(); + String innerType = null; + if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) { + if (propertyDefinition.getSchema() != null + && propertyDefinition.getSchema().getProperty() != null) { + innerType = propertyDefinition.getSchema().getProperty().getType(); + if (innerType == null) { + log.debug("Property type {} must have inner type in its declaration.", propertyType); + return falseResult; + } + } + } + + String value = null; + if (elementValue != null) { + if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) { + value = ""; + } else { + value = elementValue.toString(); + } + } + + boolean isValid = validator.isValid(value, innerType, allDataTypes); + if (false == isValid) { + log.debug("Failed to validate the value {} from type {}", value, propertyType); + return falseResult; + } + + PropertyValueConverter converter = propertyType.getConverter(); + String convertedValue = converter.convert(value, innerType, allDataTypes); + + JsonElement element = null; + if (convertedValue != null) { + if (convertedValue.isEmpty()) { + element = new JsonPrimitive(""); + } else { + try { + element = jsonParser.parse(convertedValue); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse value {} of type {}. {}", convertedValue, propertyType, e); + return falseResult; + } + } + } + buildJsonObject.add(propName, element); + + } else { + + DataTypeDefinition typeDefinition = allDataTypes.get(type); + if (typeDefinition == null) { + log.debug("The data type {] cannot be found in the given data type list.", type); + return falseResult; + } + + ImmutablePair<JsonElement, Boolean> isValid = validateAndUpdate(elementValue, + typeDefinition, allDataTypes); + + if (false == isValid.getRight().booleanValue()) { + log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName()); + return falseResult; + } + + buildJsonObject.add(propName, isValid.getLeft()); + } + + } + + return new ImmutablePair<JsonElement, Boolean>(buildJsonObject, true); + } else { + log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName()); + return falseResult; + } + + } + } + + } + + public ImmutablePair<JsonElement, Boolean> validateAndUpdate(String value, DataTypeDefinition dataTypeDefinition, + Map<String, DataTypeDefinition> allDataTypes) { + + ImmutablePair<JsonElement, Boolean> result = falseResult; + + if (value == null || value.isEmpty()) { + return trueEmptyResult; + } + + JsonElement jsonElement = null; + try { + jsonElement = jsonParser.parse(value); + } catch (JsonSyntaxException e) { + return falseResult; + } + + result = validateAndUpdate(jsonElement, dataTypeDefinition, allDataTypes); + + return result; + } + + private Map<String, PropertyDefinition> getAllProperties(DataTypeDefinition dataTypeDefinition) { + + Map<String, PropertyDefinition> allParentsProps = new HashMap<String, PropertyDefinition>(); + + while (dataTypeDefinition != null) { + + List<PropertyDefinition> currentParentsProps = dataTypeDefinition.getProperties(); + if (currentParentsProps != null) { + currentParentsProps.stream().forEach(p -> allParentsProps.put(p.getName(), p)); + } + + dataTypeDefinition = dataTypeDefinition.getDerivedFrom(); + } + + return allParentsProps; + } + + private String getValueFromJsonElement(JsonElement jsonElement) { + String value = null; + + if (jsonElement == null || jsonElement.isJsonNull()) { + value = PropertyOperation.EMPTY_VALUE; + } else { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + + return value; + } + + public boolean isValid(String value, DataTypeDefinition dataTypeDefinition, + Map<String, DataTypeDefinition> allDataTypes) { + + boolean result = false; + + if (value == null || value.isEmpty()) { + return true; + } + + JsonElement jsonElement = null; + try { + jsonElement = jsonParser.parse(value); + } catch (JsonSyntaxException e) { + log.debug("Failed to parse the value {} from type {}. {}", value, dataTypeDefinition, e); + return false; + } + + result = isValid(jsonElement, dataTypeDefinition, allDataTypes); + + return result; + } + + private boolean isValid(JsonElement jsonElement, DataTypeDefinition dataTypeDefinition, + Map<String, DataTypeDefinition> allDataTypes) { + + Map<String, PropertyDefinition> allProperties = getAllProperties(dataTypeDefinition); + + ToscaPropertyType toscaPropertyType = null; + if ((toscaPropertyType = isDataTypeDerviedFromScalarType(dataTypeDefinition)) != null) { + + PropertyTypeValidator validator = toscaPropertyType.getValidator(); + if (jsonElement == null || true == jsonElement.isJsonNull()) { + boolean valid = validator.isValid(null, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property " + dataTypeDefinition.getName() + " from type " + + dataTypeDefinition.getName()); + return false; + } + + return true; + + } else { + if (true == jsonElement.isJsonPrimitive()) { + String value = null; + if (jsonElement != null) { + if (jsonElement.toString().isEmpty()) { + value = ""; + } else { + value = jsonElement.toString(); + } + } + boolean valid = validator.isValid(value, null, allDataTypes); + if (false == valid) { + log.trace("Failed in validation of property {} from type {}. Json primitive value is {}", dataTypeDefinition.getName(), dataTypeDefinition.getName(), value); + return false; + } + + return true; + + } else { + // MAP, LIST, OTHER types cannot be applied data type + // definition scalar type. We currently cannot derived from + // map/list. (cannot add the entry schema to it) + log.debug("We cannot derive from list/map. Thus, the value cannot be not primitive since the data type {} is scalar one", dataTypeDefinition.getName()); + + return false; + } + } + } else { + + if (jsonElement == null || jsonElement.isJsonNull()) { + + return true; + + } else { + + if (jsonElement.isJsonObject()) { + + JsonObject asJsonObject = jsonElement.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + + for (Entry<String, JsonElement> entry : entrySet) { + String propName = entry.getKey(); + + JsonElement elementValue = entry.getValue(); + + PropertyDefinition propertyDefinition = allProperties.get(propName); + if (propertyDefinition == null) { + log.debug("The property {} was not found under data tpye {}", propName, dataTypeDefinition.getName()); + return false; + } + String type = propertyDefinition.getType(); + boolean isScalarType = ToscaPropertyType.isScalarType(type); + + if (true == isScalarType) { + ToscaPropertyType propertyType = ToscaPropertyType.isValidType(type); + if (propertyType == null) { + log.debug("cannot find the {} under default tosca property types", type); + return false; + } + PropertyTypeValidator validator = propertyType.getValidator(); + String innerType = null; + if (propertyType == ToscaPropertyType.LIST || propertyType == ToscaPropertyType.MAP) { + if (propertyDefinition.getSchema() != null + && propertyDefinition.getSchema().getProperty() != null) { + innerType = propertyDefinition.getSchema().getProperty().getType(); + if (innerType == null) { + log.debug("Property type {} must have inner type in its decleration.", propertyType); + return false; + } + } + } + + String value = null; + if (elementValue != null) { + if (elementValue.isJsonPrimitive() && elementValue.getAsString().isEmpty()) { + value = ""; + } else { + value = elementValue.toString(); + } + } + + boolean isValid = validator.isValid(value, innerType, allDataTypes); + if (false == isValid) { + log.debug("Failed to validate the value {} from type {}", value, propertyType); + return false; + } + + } else { + + DataTypeDefinition typeDefinition = allDataTypes.get(type); + if (typeDefinition == null) { + log.debug("The data type {} canot be found in the given data type list.", type); + return false; + } + + boolean isValid = isValid(elementValue, typeDefinition, allDataTypes); + + if (false == isValid) { + log.debug("Failed in validation of value {} from type {}", (elementValue != null ? elementValue.toString() : null), typeDefinition.getName()); + return false; + } + + } + + } + + return true; + } else { + log.debug("The value {} of type {} should be json object", (jsonElement != null ? jsonElement.toString() : null), dataTypeDefinition.getName()); + return false; + } + + } + } + + } + + // public ImmutablePair<String, Boolean> + // validateAndUpdateAndReturnString(String value, DataTypeDefinition + // dataTypeDefinition, Map<String, DataTypeDefinition> allDataTypes) { + // + // ImmutablePair<JsonElement, Boolean> result = falseResult; + // + // if (value == null || value.isEmpty()) { + // return trueStringEmptyResult; + // } + // + // JsonElement jsonElement = null; + // try { + // jsonElement = jsonParser.parse(value); + // } catch (JsonSyntaxException e) { + // return falseStringEmptyResult; + // } + // + // result = validateAndUpdate(jsonElement, dataTypeDefinition, + // allDataTypes); + // + // if (result.right.booleanValue() == false) { + // log.debug("The value {} of property from type {} is invalid", value, dataTypeDefinition.getName()); + // return new ImmutablePair<String, Boolean>(value, false); + // } + // + // String valueFromJsonElement = getValueFromJsonElement(result.left); + // + // return new ImmutablePair<String, Boolean>(valueFromJsonElement, true); + // } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java new file mode 100644 index 0000000000..2518eaa51e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class FloatValidator implements PropertyTypeValidator { + + private static FloatValidator FloatValidator = new FloatValidator(); + + public static FloatValidator getInstance() { + return FloatValidator; + } + + private FloatValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + try { + Float.parseFloat(value); + } catch (IllegalArgumentException e) { + return false; + } + + return true; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java new file mode 100644 index 0000000000..ec4051e65c --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatBooleanValidator implements PropertyTypeValidator { + + private static HeatBooleanValidator booleanValidator = new HeatBooleanValidator(); + + public static HeatBooleanValidator getInstance() { + return booleanValidator; + } + + private HeatBooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + if (value.equalsIgnoreCase("true") || value.equalsIgnoreCase("false") || value.equalsIgnoreCase("t") + || value.equalsIgnoreCase("f") || value.equalsIgnoreCase("on") || value.equalsIgnoreCase("off") + || value.equalsIgnoreCase("yes") || value.equalsIgnoreCase("no") || value.equalsIgnoreCase("y") + || value.equalsIgnoreCase("n") || value.equalsIgnoreCase("1") || value.equalsIgnoreCase("0")) { + return true; + } + + return false; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java new file mode 100644 index 0000000000..464dbf0975 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatCommaDelimitedListValidator implements PropertyTypeValidator { + + private static HeatCommaDelimitedListValidator stringValidator = new HeatCommaDelimitedListValidator(); + + public static HeatCommaDelimitedListValidator getInstance() { + return stringValidator; + } + + private HeatCommaDelimitedListValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java new file mode 100644 index 0000000000..37c4a46829 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class HeatNumberValidator implements PropertyTypeValidator { + + private static HeatNumberValidator numberValidator = new HeatNumberValidator(); + + private static FloatValidator floatValidator = FloatValidator.getInstance(); + private static IntegerValidator integerValidator = IntegerValidator.getInstance(); + + public static HeatNumberValidator getInstance() { + return numberValidator; + } + + private HeatNumberValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + boolean valid = integerValidator.isValid(value, null, allDataTypes); + + if (!valid) { + valid = floatValidator.isValid(value, null, allDataTypes); + } + + return valid; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java new file mode 100644 index 0000000000..0e7b7f6648 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class HeatStringValidator implements PropertyTypeValidator { + + private static HeatStringValidator stringValidator = new HeatStringValidator(); + + public static HeatStringValidator getInstance() { + return stringValidator; + } + + private HeatStringValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java new file mode 100644 index 0000000000..61d321c45e --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class IntegerValidator implements PropertyTypeValidator { + + private static IntegerValidator integerValidator = new IntegerValidator(); + + private IntegerValidator() { + } + + public static IntegerValidator getInstance() { + return integerValidator; + } + + private class PatternBase { + public PatternBase(Pattern pattern, Integer base) { + this.pattern = pattern; + this.base = base; + } + + Pattern pattern; + Integer base; + } + + private PatternBase base8Pattern = new PatternBase(Pattern.compile("([-+])?0o([0-7]+)"), 8); + private PatternBase base10Pattern = new PatternBase(Pattern.compile("([-+])?(0|[1-9][0-9]*)"), 10); + private PatternBase base16Pattern = new PatternBase(Pattern.compile("([-+])?0x([0-9a-fA-F]+)"), 16); + + private PatternBase[] patterns = { base10Pattern, base8Pattern, base16Pattern }; + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + for (PatternBase patternBase : patterns) { + Matcher matcher = patternBase.pattern.matcher(value); + Long parsed = null; + if (matcher.matches()) { + try { + parsed = Long.parseLong(matcher.group(2), patternBase.base); + if (matcher.group(1) != null && matcher.group(1).compareTo("-") == 0) { + parsed *= -1; + } + return (Integer.MIN_VALUE <= parsed && parsed <= (Integer.MAX_VALUE)) ? true : false; + } catch (NumberFormatException e) { + return false; + } + } + } + return false; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java new file mode 100644 index 0000000000..164fe62792 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.io.StringReader; +import java.util.Map; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.GsonFactory; +import org.openecomp.sdc.common.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +public class JsonValidator implements PropertyTypeValidator { + + private static JsonValidator jsonValidator = new JsonValidator(); + + private static Logger log = LoggerFactory.getLogger(JsonValidator.class.getName()); + + private static JsonParser jsonParser = new JsonParser(); + + public static JsonValidator getInstance() { + return jsonValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || value.isEmpty()) { + return true; + } + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + jsonParser.parse(jsonReader); + } catch (JsonSyntaxException e) { + log.debug("Error parsing JSON property", e); + return false; + } + return true; + + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java new file mode 100644 index 0000000000..4b11e26d05 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class KeyValidator implements PropertyTypeValidator { + + public static final int STRING_MAXIMUM_LENGTH = 100; + + private static KeyValidator keyValidator = new KeyValidator(); + + public static KeyValidator getInstance() { + return keyValidator; + } + + private KeyValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return false; + } + + if (value.length() > STRING_MAXIMUM_LENGTH) { + return false; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + return ValidationUtils.validateIsEnglish(coverted); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java new file mode 100644 index 0000000000..92834690b8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +public class ListValidator implements PropertyTypeValidator { + + private static ListValidator listValidator = new ListValidator(); + + private static Logger log = LoggerFactory.getLogger(ListValidator.class.getName()); + Gson gson = new Gson(); + + private static JsonParser jsonParser = new JsonParser(); + + private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + public static ListValidator getInstance() { + return listValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + log.debug("Going to validate value {} with inner type {}", value, innerType); + + if (value == null || value == "") { + return true; + } + if (innerType == null) { + return false; + } + + PropertyTypeValidator innerValidator; + + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerValidator = ToscaPropertyType.STRING.getValidator(); + break; + case INTEGER: + innerValidator = ToscaPropertyType.INTEGER.getValidator(); + break; + case FLOAT: + innerValidator = ToscaPropertyType.FLOAT.getValidator(); + break; + case BOOLEAN: + innerValidator = ToscaPropertyType.BOOLEAN.getValidator(); + break; + case JSON: + innerValidator = ToscaPropertyType.JSON.getValidator(); + break; + default: + log.debug("inner Tosca Type is unknown: {}", innerToscaType); + return false; + } + + } else { + log.debug("inner Tosca Type is: {}", innerType); + + boolean isValid = validateComplexInnerType(value, innerType, allDataTypes); + log.debug("Finish to validate value {} of list with inner type {}. result is: {}", value, innerType, isValid); + return isValid; + } + + try { + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + String element = JsonUtils.toString(currentValue); + if (!innerValidator.isValid(element, null, allDataTypes)) { + log.debug("validation of element : {} failed", element); + return false; + } + + } + return true; + + } catch (JsonSyntaxException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("List Validator"); + } + + return false; + + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } + + private boolean validateComplexInnerType(String value, String innerType, + Map<String, DataTypeDefinition> allDataTypes) { + + DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType); + if (innerDataTypeDefinition == null) { + log.debug("Data type {} cannot be found in our data types.", innerType); + return false; + } + + try { + + JsonArray jo = (JsonArray) jsonParser.parse(value); + int size = jo.size(); + for (int i = 0; i < size; i++) { + JsonElement currentValue = jo.get(i); + if (currentValue != null) { + String element = JsonUtils.toString(currentValue); + boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition, + allDataTypes); + if (isValid == false) { + log.debug("Cannot parse value {} from type {} in list parameter", currentValue, innerType); + return false; + } + } + } + + } catch (Exception e) { + log.debug("Error when parsing JSON of object of type ", e); + return false; + } + + return true; + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java new file mode 100644 index 0000000000..c8ffc3f4b8 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java @@ -0,0 +1,184 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.util.JsonUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; + +/* + * Property Type Map correct usage: + * null key null value = Yaml reader error +valid key null value = key & value deleted +duplicated keys = last key is taken +mismatch between inner type and values type = returned mismatch in data type +validators and converters works the same as before + +Types: +when written line by line : + key1 : val1 + key2 : val2 +key1 and val does not need " " , even if val1 is a string. + +when written as one line : {"key1":val1 , "key2":val2} +Keys always need " " around them. + */ +public class MapValidator implements PropertyTypeValidator { + + private static MapValidator mapValidator = new MapValidator(); + + private static Logger log = LoggerFactory.getLogger(MapValidator.class.getName()); + Gson gson = new Gson(); + + private static DataTypeValidatorConverter dataTypeValidatorConverter = DataTypeValidatorConverter.getInstance(); + + private static JsonParser jsonParser = new JsonParser(); + + public static MapValidator getInstance() { + return mapValidator; + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || value == "") { + return true; + } + if (innerType == null) { + return false; + } + + PropertyTypeValidator innerValidator; + PropertyTypeValidator keyValidator = ToscaPropertyType.KEY.getValidator(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(innerType); + + if (innerToscaType != null) { + switch (innerToscaType) { + case STRING: + innerValidator = ToscaPropertyType.STRING.getValidator(); + break; + case INTEGER: + innerValidator = ToscaPropertyType.INTEGER.getValidator(); + break; + case FLOAT: + innerValidator = ToscaPropertyType.FLOAT.getValidator(); + break; + case BOOLEAN: + innerValidator = ToscaPropertyType.BOOLEAN.getValidator(); + break; + case JSON: + innerValidator = ToscaPropertyType.JSON.getValidator(); + break; + default: + log.debug("inner Tosca Type is unknown: {}", innerToscaType); + return false; + } + + } else { + log.debug("inner Tosca Type is: {}", innerType); + + boolean isValid = validateComplexInnerType(value, innerType, allDataTypes); + log.debug("Finish to validate value {} of map with inner type {}. Result is {}", value, innerType, isValid); + return isValid; + + } + + try { + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + for (Entry<String, JsonElement> entry : entrySet) { + String currentKey = entry.getKey(); + JsonElement jsonValue = entry.getValue(); + + String element = JsonUtils.toString(jsonValue); + + if (!innerValidator.isValid(element, null, allDataTypes) + || !keyValidator.isValid(entry.getKey(), null, allDataTypes)) { + log.debug("validation of key : {}, element: {} failed", currentKey, entry.getValue()); + return false; + } + } + + return true; + } catch (JsonSyntaxException e) { + log.debug("Failed to parse json : {}. {}", value, e); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Map Validator"); + } + + return false; + + } + + private boolean validateComplexInnerType(String value, String innerType, + Map<String, DataTypeDefinition> allDataTypes) { + + DataTypeDefinition innerDataTypeDefinition = allDataTypes.get(innerType); + if (innerDataTypeDefinition == null) { + log.debug("Data type {} cannot be found in our data types.", innerType); + return false; + } + + try { + JsonElement jsonObject = jsonParser.parse(value); + JsonObject asJsonObject = jsonObject.getAsJsonObject(); + Set<Entry<String, JsonElement>> entrySet = asJsonObject.entrySet(); + for (Entry<String, JsonElement> entry : entrySet) { + String currentKey = entry.getKey(); + JsonElement currentValue = entry.getValue(); + + if (currentValue != null) { + String element = JsonUtils.toString(currentValue); + boolean isValid = dataTypeValidatorConverter.isValid(element, innerDataTypeDefinition, + allDataTypes); + if (isValid == false) { + log.debug("Cannot parse value {} from type {} of key {}", currentValue, innerType, currentKey); + return false; + } + } + } + + } catch (Exception e) { + log.debug("Cannot parse value {} of map from inner type {}. {}", value, innerType, e); + return false; + } + + return true; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java new file mode 100644 index 0000000000..35862148f9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public interface PropertyTypeValidator { + + boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes); + + boolean isValid(String value, String innerType); + /* + * The value format should be validated according to the “Property Type�? : + * “integer�? - valid tag:yaml.org,2002:int , the number base 8,10,18 should + * be handled ( hint : to validate by calling parseInt( + * s,10)/parseInt(s,16)/parseInt(s,8) or just regexp [-+]?[0-9]+ for Base 10 + * , [-+]?0[0-7]+ for Base 8 , [-+]?0x[0-9a-fA-F]+ for Base 16 + * + * “float�? - valid tag:yaml.org,2002:float , parseFloat() “boolean�? - valid + * tag:yaml.org,2002:bool : can be only “true�? or “false�? ( upper case + * characters should be converted to lower case : TRUE ->true, True->true + * “string�? - valid tag:yaml.org,2002:str and limited to 100 chars. + * + */ + +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java new file mode 100644 index 0000000000..06994505a9 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Map; + +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.ToscaValidatorsConfig; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StringValidator implements PropertyTypeValidator { + + public static final int DEFAULT_STRING_MAXIMUM_LENGTH = 100; + + public static int STRING_MAXIMUM_LENGTH = DEFAULT_STRING_MAXIMUM_LENGTH; + + private static Logger log = LoggerFactory.getLogger(StringValidator.class.getName()); + + private static StringValidator stringValidator = new StringValidator(); + + public static StringValidator getInstance() { + return stringValidator; + } + + private StringValidator() { + if (ConfigurationManager.getConfigurationManager() != null) { + ToscaValidatorsConfig toscaValidators = ConfigurationManager.getConfigurationManager().getConfiguration() + .getToscaValidators(); + log.debug("toscaValidators={}", toscaValidators); + if (toscaValidators != null) { + Integer stringMaxLength = toscaValidators.getStringMaxLength(); + if (stringMaxLength != null) { + STRING_MAXIMUM_LENGTH = stringMaxLength; + } + } + } + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> allDataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + if (value.length() > STRING_MAXIMUM_LENGTH) { + log.debug("parameter String length {} is higher the configured({})", value.length(), STRING_MAXIMUM_LENGTH); + return false; + } + String coverted = ValidationUtils.removeNoneUtf8Chars(value); + boolean isValid = ValidationUtils.validateIsAscii(coverted); + + if (false == isValid) { + log.debug("parameter String value {} is not ascii string.", (value != null ? value.substring(0, Math.min(value.length(), 20)) : null)); + } + + return isValid; + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java new file mode 100644 index 0000000000..7f8dff42d0 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.validators; + +import java.util.Arrays; +import java.util.Map; + +import org.openecomp.sdc.be.model.DataTypeDefinition; + +public class ToscaBooleanValidator implements PropertyTypeValidator { + + private static ToscaBooleanValidator booleanValidator = new ToscaBooleanValidator(); + + private static String[] validValues = { "true", "on", "yes", "y", "false", "off", "no", "n" }; + + public static ToscaBooleanValidator getInstance() { + return booleanValidator; + } + + private ToscaBooleanValidator() { + + } + + @Override + public boolean isValid(String value, String innerType, Map<String, DataTypeDefinition> dataTypes) { + + if (value == null || true == value.isEmpty()) { + return true; + } + + return (Arrays.stream(validValues).filter(str -> str.equalsIgnoreCase(value)).toArray().length == 1); + } + + @Override + public boolean isValid(String value, String innerType) { + return isValid(value, innerType, null); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java new file mode 100644 index 0000000000..dadfd49831 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.version; + +import org.openecomp.sdc.be.model.tosca.constraints.exception.TechnicalException; + +public class ApplicationVersionException extends TechnicalException { + + private static final long serialVersionUID = -5192834855057177252L; + + public ApplicationVersionException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationVersionException(String message) { + super(message); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java new file mode 100644 index 0000000000..905d8bf3bc --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java @@ -0,0 +1,463 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.version; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; +import java.util.Locale; +import java.util.Properties; +import java.util.Stack; + +/** + * Generic implementation of version comparison. + * + * <p> + * Features: + * <ul> + * <li>mixing of '<code>-</code>' (dash) and '<code>.</code>' (dot) + * separators,</li> + * <li>transition between characters and digits also constitutes a separator: + * <code>1.0alpha1 => [1, 0, alpha, 1]</code></li> + * <li>unlimited number of version components,</li> + * <li>version components in the text can be digits or strings,</li> + * <li>strings are checked for well-known qualifiers and the qualifier ordering + * is used for version ordering. Well-known qualifiers (case insensitive) are: + * <ul> + * <li><code>alpha</code> or <code>a</code></li> + * <li><code>beta</code> or <code>b</code></li> + * <li><code>milestone</code> or <code>m</code></li> + * <li><code>rc</code> or <code>cr</code></li> + * <li><code>snapshot</code></li> + * <li><code>(the empty string)</code> or <code>ga</code> or + * <code>final</code></li> + * <li><code>sp</code></li> + * </ul> + * Unknown qualifiers are considered after known qualifiers, with lexical order + * (always case insensitive),</li> + * <li>a dash usually precedes a qualifier, and is always less important than + * something preceded with a dot.</li> + * </ul> + * </p> + * + * @see <a href= + * "https://cwiki.apache.org/confluence/display/MAVENOLD/Versioning">"Versioning" + * on Maven Wiki</a> + * @author <a href="mailto:kenney@apache.org">Kenney Westerhof</a> + * @author <a href="mailto:hboutemy@apache.org">Hervé Boutemy</a> + */ +public class ComparableVersion implements Comparable<ComparableVersion> { + private String value; + + private String canonical; + + private ListItem items; + + private interface Item { + int INTEGER_ITEM = 0; + int STRING_ITEM = 1; + int LIST_ITEM = 2; + + int compareTo(Item item); + + int getType(); + + boolean isNull(); + } + + /** + * Represents a numeric item in the version item list. + */ + private static class IntegerItem implements Item { + private static final BigInteger BIG_INTEGER_ZERO = new BigInteger("0"); + + private final BigInteger value; + + public static final IntegerItem ZERO = new IntegerItem(); + + private IntegerItem() { + this.value = BIG_INTEGER_ZERO; + } + + public IntegerItem(String str) { + this.value = new BigInteger(str); + } + + @Override + public int getType() { + return INTEGER_ITEM; + } + + @Override + public boolean isNull() { + return BIG_INTEGER_ZERO.equals(value); + } + + @Override + public int compareTo(Item item) { + if (item == null) { + return BIG_INTEGER_ZERO.equals(value) ? 0 : 1; // 1.0 == 1, 1.1 + // > 1 + } + + switch (item.getType()) { + case INTEGER_ITEM: + return value.compareTo(((IntegerItem) item).value); + + case STRING_ITEM: + return 1; // 1.1 > 1-sp + + case LIST_ITEM: + return 1; // 1.1 > 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + return value.toString(); + } + } + + /** + * Represents a string in the version item list, usually a qualifier. + */ + private static class StringItem implements Item { + private static final String[] QUALIFIERS = { "alpha", "beta", "milestone", "rc", "snapshot", "", "sp" }; + + private static final List<String> _QUALIFIERS = Arrays.asList(QUALIFIERS); + + private static final Properties ALIASES = new Properties(); + static { + ALIASES.put("ga", ""); + ALIASES.put("final", ""); + ALIASES.put("cr", "rc"); + } + + /** + * A comparable value for the empty-string qualifier. This one is used + * to determine if a given qualifier makes the version older than one + * without a qualifier, or more recent. + */ + private static final String RELEASE_VERSION_INDEX = String.valueOf(_QUALIFIERS.indexOf("")); + + private String value; + + public StringItem(String value, boolean followedByDigit) { + if (followedByDigit && value.length() == 1) { + // a1 = alpha-1, b1 = beta-1, m1 = milestone-1 + switch (value.charAt(0)) { + case 'a': + value = "alpha"; + break; + case 'b': + value = "beta"; + break; + case 'm': + value = "milestone"; + break; + } + } + this.value = ALIASES.getProperty(value, value); + } + + @Override + public int getType() { + return STRING_ITEM; + } + + @Override + public boolean isNull() { + return (comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX) == 0); + } + + /** + * Returns a comparable value for a qualifier. + * + * This method takes into account the ordering of known qualifiers then + * unknown qualifiers with lexical ordering. + * + * just returning an Integer with the index here is faster, but requires + * a lot of if/then/else to check for -1 or QUALIFIERS.size and then + * resort to lexical ordering. Most comparisons are decided by the first + * character, so this is still fast. If more characters are needed then + * it requires a lexical sort anyway. + * + * @param qualifier + * @return an equivalent value that can be used with lexical comparison + */ + public static String comparableQualifier(String qualifier) { + int i = _QUALIFIERS.indexOf(qualifier); + + return i == -1 ? (_QUALIFIERS.size() + "-" + qualifier) : String.valueOf(i); + } + + // @Override + public int compareTo(Item item) { + if (item == null) { + // 1-rc < 1, 1-ga > 1 + return comparableQualifier(value).compareTo(RELEASE_VERSION_INDEX); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1.any < 1.1 ? + + case STRING_ITEM: + return comparableQualifier(value).compareTo(comparableQualifier(((StringItem) item).value)); + + case LIST_ITEM: + return -1; // 1.any < 1-1 + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + return value; + } + } + + /** + * Represents a version list item. This class is used both for the global + * item list and for sub-lists (which start with '-(number)' in the version + * specification). + */ + private static class ListItem extends ArrayList<Item> implements Item { + + private static final long serialVersionUID = -4740226741001149657L; + + @Override + public int getType() { + return LIST_ITEM; + } + + @Override + public boolean isNull() { + return (size() == 0); + } + + void normalize() { + for (ListIterator<Item> iterator = listIterator(size()); iterator.hasPrevious();) { + Item item = iterator.previous(); + if (item.isNull()) { + iterator.remove(); // remove null trailing items: 0, "", + // empty list + } else { + break; + } + } + } + + @Override + public int compareTo(Item item) { + if (item == null) { + if (size() == 0) { + return 0; // 1-0 = 1- (normalize) = 1 + } + Item first = get(0); + return first.compareTo(null); + } + switch (item.getType()) { + case INTEGER_ITEM: + return -1; // 1-1 < 1.0.x + + case STRING_ITEM: + return 1; // 1-1 > 1-sp + + case LIST_ITEM: + Iterator<Item> left = iterator(); + Iterator<Item> right = ((ListItem) item).iterator(); + + while (left.hasNext() || right.hasNext()) { + Item l = left.hasNext() ? left.next() : null; + Item r = right.hasNext() ? right.next() : null; + + int result = 0; + if (r != null && l != null) { + result = l.compareTo(r); + } else if (r == null && l == null) { + result = 0; + } else if (l == null) { + result = -1; + } else { + result = 1; + } + + // if this is shorter, then invert the compare and mul with + // -1 + // int result = (l == null ? (r == null ? 0 : -1 * + // r.compareTo(l)) : l.compareTo(r)); + + if (result != 0) { + return result; + } + } + + return 0; + + default: + throw new RuntimeException("invalid item: " + item.getClass()); + } + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder("("); + for (Iterator<Item> iter = iterator(); iter.hasNext();) { + buffer.append(iter.next()); + if (iter.hasNext()) { + buffer.append(','); + } + } + buffer.append(')'); + return buffer.toString(); + } + } + + public ComparableVersion(String version) { + parseVersion(version); + } + + public final void parseVersion(String version) { + this.value = version; + + items = new ListItem(); + + version = version.toLowerCase(Locale.ENGLISH); + + ListItem list = items; + + Stack<Item> stack = new Stack<Item>(); + stack.push(list); + + boolean isDigit = false; + + int startIndex = 0; + + for (int i = 0; i < version.length(); i++) { + char c = version.charAt(i); + + if (c == '.') { + if (i == startIndex) { + list.add(IntegerItem.ZERO); + } else { + list.add(parseItem(isDigit, version.substring(startIndex, i))); + } + startIndex = i + 1; + } else if (c == '-') { + if (i == startIndex) { + list.add(IntegerItem.ZERO); + } else { + list.add(parseItem(isDigit, version.substring(startIndex, i))); + } + startIndex = i + 1; + + if (isDigit) { + list.normalize(); // 1.0-* = 1-* + + if ((i + 1 < version.length()) && Character.isDigit(version.charAt(i + 1))) { + // new ListItem only if previous were digits and new + // char is a digit, + // ie need to differentiate only 1.1 from 1-1 + list.add(list = new ListItem()); + + stack.push(list); + } + } + } else if (Character.isDigit(c)) { + if (!isDigit && i > startIndex) { + list.add(new StringItem(version.substring(startIndex, i), true)); + startIndex = i; + } + + isDigit = true; + } else { + if (isDigit && i > startIndex) { + list.add(parseItem(true, version.substring(startIndex, i))); + startIndex = i; + } + + isDigit = false; + } + } + + if (version.length() > startIndex) { + list.add(parseItem(isDigit, version.substring(startIndex))); + } + + while (!stack.isEmpty()) { + list = (ListItem) stack.pop(); + list.normalize(); + } + + canonical = items.toString(); + } + + private static Item parseItem(boolean isDigit, String buf) { + return isDigit ? new IntegerItem(buf) : new StringItem(buf, false); + } + + @Override + public int compareTo(ComparableVersion o) { + return items.compareTo(o.items); + } + + @Override + public String toString() { + return value; + } + + @Override + public boolean equals(Object o) { + return (o instanceof ComparableVersion) && canonical.equals(((ComparableVersion) o).canonical); + } + + @Override + public int hashCode() { + return canonical.hashCode(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java new file mode 100644 index 0000000000..268ee28b96 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java @@ -0,0 +1,192 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.model.tosca.version; + +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import java.util.StringTokenizer; +import java.util.regex.Pattern; + +/** + * Default implementation of artifact versioning. + * + * @author <a href="mailto:brett@apache.org">Brett Porter</a> + */ +public class Version implements Comparable<Version> { + private Integer majorVersion; + + private Integer minorVersion; + + private Integer incrementalVersion; + + private Integer buildNumber; + + private String qualifier; + + private ComparableVersion comparable; + + public Version(String version) { + parseVersion(version); + } + + @Override + public int hashCode() { + return 11 + comparable.hashCode(); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } + + if (!(other instanceof Version)) { + return false; + } + + return compareTo((Version) other) == 0; + } + + public int compareTo(Version otherVersion) { + return this.comparable.compareTo(otherVersion.comparable); + } + + public int getMajorVersion() { + return majorVersion != null ? majorVersion : 0; + } + + public int getMinorVersion() { + return minorVersion != null ? minorVersion : 0; + } + + public int getIncrementalVersion() { + return incrementalVersion != null ? incrementalVersion : 0; + } + + public int getBuildNumber() { + return buildNumber != null ? buildNumber : 0; + } + + public String getQualifier() { + return qualifier; + } + + public final void parseVersion(String version) { + comparable = new ComparableVersion(version); + + int index = version.indexOf("-"); + + String part1; + String part2 = null; + + if (index < 0) { + part1 = version; + } else { + part1 = version.substring(0, index); + part2 = version.substring(index + 1); + } + + if (part2 != null) { + try { + if ((part2.length() == 1) || !part2.startsWith("0")) { + buildNumber = Integer.valueOf(part2); + } else { + qualifier = part2; + } + } catch (NumberFormatException e) { + qualifier = part2; + } + } + + if ((!part1.contains(".")) && !part1.startsWith("0")) { + try { + majorVersion = Integer.valueOf(part1); + } catch (NumberFormatException e) { + // qualifier is the whole version, including "-" + qualifier = version; + buildNumber = null; + } + } else { + boolean fallback = false; + + StringTokenizer tok = new StringTokenizer(part1, "."); + try { + majorVersion = getNextIntegerToken(tok); + if (tok.hasMoreTokens()) { + minorVersion = getNextIntegerToken(tok); + } + if (tok.hasMoreTokens()) { + incrementalVersion = getNextIntegerToken(tok); + } + if (tok.hasMoreTokens()) { + qualifier = tok.nextToken(); + fallback = Pattern.compile("\\d+").matcher(qualifier).matches(); + } + + // string tokenzier won't detect these and ignores them + if (part1.contains("..") || part1.startsWith(".") || part1.endsWith(".")) { + fallback = true; + } + } catch (NumberFormatException e) { + fallback = true; + } + + if (fallback) { + // qualifier is the whole version, including "-" + qualifier = version; + majorVersion = null; + minorVersion = null; + incrementalVersion = null; + buildNumber = null; + } + } + } + + private static Integer getNextIntegerToken(StringTokenizer tok) { + String s = tok.nextToken(); + if ((s.length() > 1) && s.startsWith("0")) { + throw new NumberFormatException("Number part has a leading 0: '" + s + "'"); + } + return Integer.valueOf(s); + } + + @Override + public String toString() { + return comparable.toString(); + } +} diff --git a/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java new file mode 100644 index 0000000000..f95a89db62 --- /dev/null +++ b/catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END========================================================= + */ + +package org.openecomp.sdc.be.unittests.utils; + +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.CapabilityInstData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.be.resources.data.PropertyValueData; +import org.openecomp.sdc.be.resources.data.RequirementData; + +public final class FactoryUtils { + private FactoryUtils() { + }; + + public static final class Constants { + public static final String DEFAULT_CAPABILITY_TYPE = "tosca.capabilities.Node"; + } + + public static Resource createVFWithRI(String riVersion) { + Resource vf = createVF(); + ComponentInstance ri = createResourceInstanceWithVersion(riVersion); + addComponentInstanceToVF(vf, ri); + return vf; + } + + public static Resource createVF() { + Resource resource = new Resource(); + String uniqueId = UUID.randomUUID().toString(); + resource.setUniqueId(uniqueId); + return resource; + } + + public static void addComponentInstanceToVF(Resource vf, ComponentInstance resourceInstance) { + List<ComponentInstance> componentsInstances = vf.getComponentInstances() != null ? vf.getComponentInstances() + : new ArrayList<>(); + componentsInstances.add(resourceInstance); + vf.setComponentInstances(componentsInstances); + } + + public static ComponentInstance createResourceInstance() { + ComponentInstance ri = new ComponentInstance(); + ri.setComponentVersion("0.1"); + String uniqueId = UUID.randomUUID().toString(); + ri.setComponentUid(uniqueId); + ri.setUniqueId(uniqueId); + ri.setName("genericRI" + uniqueId); + ri.setOriginType(OriginTypeEnum.VF); + return ri; + + } + + public static ComponentInstance createResourceInstanceWithVersion(String riVersion) { + ComponentInstance ri = createResourceInstance(); + ri.setComponentVersion(riVersion); + return ri; + } + + public static CapabilityData createCapabilityData() { + CapabilityData capData = new CapabilityData(); + String uniqueId = UUID.randomUUID().toString(); + capData.setUniqueId(uniqueId); + + capData.setType(Constants.DEFAULT_CAPABILITY_TYPE); + return capData; + } + + public static RequirementData createRequirementData() { + RequirementData reqData = new RequirementData(); + String uniqueId = UUID.randomUUID().toString(); + reqData.setUniqueId(uniqueId); + return reqData; + } + + public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionAddProperties( + CapabilityData capData) { + CapabilityDefinition capDef = new CapabilityDefinition(); + capDef.setName("Cap2"); + capDef.setDescription(capData.getDescription()); + capDef.setUniqueId(capData.getUniqueId()); + capDef.setValidSourceTypes(capData.getValidSourceTypes()); + capDef.setType(capData.getType()); + capDef.setProperties(new ArrayList<>()); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setDefaultValue("defhost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setDefaultValue("defport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(port); + return capDef; + } + + public static List<ComponentInstanceProperty> createComponentInstancePropertyList() { + List<ComponentInstanceProperty> properties = new ArrayList<>(); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setValue("newhost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + properties.add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setValue("newport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + properties.add(port); + return properties; + } + + public static RequirementDefinition convertRequirementDataIDToRequirementDefinition(String reqDataId) { + RequirementDefinition reqDef = new RequirementDefinition(); + reqDef.setUniqueId(reqDataId); + reqDef.setCapability(Constants.DEFAULT_CAPABILITY_TYPE); + return reqDef; + } + + public static GraphEdge createGraphEdge() { + GraphEdge graphEdge = new GraphEdge(); + return graphEdge; + } + + public static CapabilityInstData createCapabilityInstData() { + CapabilityInstData capInstData = new CapabilityInstData(); + String uniqueId = UUID.randomUUID().toString(); + capInstData.setUniqueId(uniqueId); + return capInstData; + } + + public static PropertyValueData createPropertyData() { + PropertyValueData propData = new PropertyValueData(); + String uniqueId = UUID.randomUUID().toString(); + propData.setValue("localhost"); + propData.setUniqueId(uniqueId); + return propData; + } + + public static PropertyData convertCapabilityDefinitionToCapabilityData(PropertyDefinition propDef) { + PropertyData propData = new PropertyData(); + propData.getPropertyDataDefinition().setUniqueId(propDef.getUniqueId()); + propData.getPropertyDataDefinition().setDefaultValue(propDef.getDefaultValue()); + return propData; + } + + public static CapabilityDefinition convertCapabilityDataToCapabilityDefinitionRoot(CapabilityData capData) { + CapabilityDefinition capDef = new CapabilityDefinition(); + capDef.setName("Cap1"); + capDef.setDescription(capData.getDescription()); + capDef.setUniqueId(capData.getUniqueId()); + capDef.setValidSourceTypes(capData.getValidSourceTypes()); + capDef.setType(capData.getType()); + capDef.setProperties(new ArrayList<>()); + ComponentInstanceProperty host = new ComponentInstanceProperty(); + host.setUniqueId(UUID.randomUUID().toString()); + host.setName("host"); + host.setDefaultValue("roothost"); + host.setType("string"); + + host.setSchema(new SchemaDefinition()); + host.getSchema().setProperty(new PropertyDataDefinition()); + host.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(host); + ComponentInstanceProperty port = new ComponentInstanceProperty(); + port.setName("port"); + port.setDefaultValue("rootport"); + port.setUniqueId(UUID.randomUUID().toString()); + port.setType("string"); + + port.setSchema(new SchemaDefinition()); + port.getSchema().setProperty(new PropertyDataDefinition()); + port.getSchema().getProperty().setType("string"); + + capDef.getProperties().add(port); + return capDef; + } +} |