summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java4
-rw-r--r--adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V8.5__AddCloudOwner.sql13
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRegionRestV1.java6
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRestImpl.java70
-rw-r--r--adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java9
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/cloudregion/CloudRegionRestImplTest.java34
-rw-r--r--adapters/mso-requests-db-adapter/src/main/resources/db/migration/V8.2__Fix_Invalid_Request_Status.sql4
-rw-r--r--bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/CompleteMsoProcess.groovy2
-rw-r--r--bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSDNCNetworkResource.groovy19
-rw-r--r--bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DeleteSDNCNetworkResource.groovy25
-rw-r--r--bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoDeleteE2EServiceInstance.groovy11
-rw-r--r--bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoDeleteE2EServiceInstance.bpmn3
-rw-r--r--bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasks.java4
-rw-r--r--bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasksTest.java4
-rw-r--r--mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/CloudSite.java15
-rw-r--r--mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/NetworkTechnologyReference.java101
-rw-r--r--mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/NetworkTechnologyReferenceRepository.java32
-rw-r--r--mso-catalog-db/src/test/resources/data.sql2
-rw-r--r--mso-catalog-db/src/test/resources/schema.sql1
19 files changed, 319 insertions, 40 deletions
diff --git a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
index f5464645d6..97ba7828c0 100644
--- a/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
+++ b/adapters/mso-adapter-utils/src/main/java/org/onap/so/openstack/utils/MsoHeatUtils.java
@@ -33,6 +33,7 @@ import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.onap.logging.filter.base.ErrorCode;
import org.onap.logging.ref.slf4j.ONAPLogConstants;
import org.onap.so.adapters.vdu.CloudInfo;
import org.onap.so.adapters.vdu.PluginAction;
@@ -45,14 +46,11 @@ import org.onap.so.adapters.vdu.VduPlugin;
import org.onap.so.adapters.vdu.VduStateType;
import org.onap.so.adapters.vdu.VduStatus;
import org.onap.so.cloud.authentication.KeystoneAuthHolder;
-import org.onap.so.db.catalog.beans.CloudIdentity;
-import org.onap.so.db.catalog.beans.CloudSite;
import org.onap.so.db.catalog.beans.HeatTemplate;
import org.onap.so.db.catalog.beans.HeatTemplateParam;
import org.onap.so.db.request.beans.CloudApiRequests;
import org.onap.so.db.request.beans.InfraActiveRequests;
import org.onap.so.db.request.client.RequestsDbClient;
-import org.onap.logging.filter.base.ErrorCode;
import org.onap.so.logger.MessageEnum;
import org.onap.so.openstack.beans.CreateStackRequest;
import org.onap.so.openstack.beans.HeatStatus;
diff --git a/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V8.5__AddCloudOwner.sql b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V8.5__AddCloudOwner.sql
new file mode 100644
index 0000000000..92502e2696
--- /dev/null
+++ b/adapters/mso-catalog-db-adapter/src/main/resources/db/migration/V8.5__AddCloudOwner.sql
@@ -0,0 +1,13 @@
+use catalogdb;
+
+
+ALTER TABLE cloud_sites
+ ADD COLUMN IF NOT EXISTS CLOUD_OWNER varchar(255);
+
+
+CREATE TABLE IF NOT EXISTS `network_technology_reference` (
+ `ID` INT(11) NOT NULL AUTO_INCREMENT,
+ `NETWORK_TECHNOLOGY` varchar(200) NOT NULL ,
+ `CLOUD_OWNER` varchar(200) NOT NULL,
+ PRIMARY KEY (`ID`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1; \ No newline at end of file
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRegionRestV1.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRegionRestV1.java
index 780480507b..6cf42e1433 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRegionRestV1.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRegionRestV1.java
@@ -56,7 +56,6 @@ public class CloudRegionRestV1 {
private CloudRestImpl cloudRestImpl;
@POST
- @Path("{cloud-region-id}/{cloud-owner}")
@Consumes({MediaType.APPLICATION_JSON})
@Produces({MediaType.APPLICATION_JSON})
@ApiOperation(value = "CreateCloudRegion", response = Response.class,
@@ -65,9 +64,8 @@ public class CloudRegionRestV1 {
@ApiResponse(code = 500, message = "Create Cloud Region has failed")})
public Response createCloudRegion(
@ApiParam(value = "cloud-region-id", required = true) @PathParam("cloud-region-id") String cloudRegionId,
- @ApiParam(value = "cloud-owner", required = true) @PathParam("cloud-owner") String cloudOwner,
@ApiParam(value = "CloudSite", required = true) final CloudSite cloudSite) {
- cloudRestImpl.createCloudRegion(cloudSite, cloudOwner);
+ cloudRestImpl.createCloudRegion(cloudSite);
return Response.status(HttpStatus.SC_CREATED).build();
}
@@ -96,7 +94,7 @@ public class CloudRegionRestV1 {
@ApiParam(value = "cloud-region-id", required = true) @PathParam("cloud-region-id") String cloudRegionId,
@ApiParam(value = "cloud-owner", required = true) @PathParam("cloud-owner") String cloudOwner,
@ApiParam(value = "CloudSite", required = true) final CloudSite cloudSite) {
- cloudRestImpl.updateCloudRegion(cloudSite, cloudOwner);
+ cloudRestImpl.updateCloudRegion(cloudSite);
return Response.status(HttpStatus.SC_OK).build();
}
}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRestImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRestImpl.java
index 4cde8655ae..380f42fa69 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRestImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/cloudregion/CloudRestImpl.java
@@ -1,13 +1,21 @@
package org.onap.so.adapters.cloudregion;
+import java.util.List;
import java.util.Optional;
import org.onap.aai.domain.yang.CloudRegion;
+import org.onap.aai.domain.yang.Complex;
+import org.onap.aai.domain.yang.NetworkTechnologies;
+import org.onap.so.client.aai.AAIObjectPlurals;
import org.onap.so.client.aai.AAIObjectType;
import org.onap.so.client.aai.AAIResourcesClient;
+import org.onap.so.client.aai.entities.uri.AAIPluralResourceUri;
import org.onap.so.client.aai.entities.uri.AAIResourceUri;
import org.onap.so.client.aai.entities.uri.AAIUriFactory;
import org.onap.so.db.catalog.beans.CloudSite;
+import org.onap.so.db.catalog.beans.NetworkTechnologyReference;
import org.onap.so.db.catalog.client.CatalogDbClient;
+import org.onap.so.db.catalog.data.repository.NetworkTechnologyReferenceRepository;
+import org.onap.so.db.catalog.utils.MavenLikeVersioning;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@@ -21,14 +29,17 @@ public class CloudRestImpl {
private AAIResourcesClient aaiClient;
@Autowired
+ private NetworkTechnologyReferenceRepository ctrRepo;
+
+ @Autowired
private CatalogDbClient catalogDBClient;
- public void createCloudRegion(CloudSite cloudSite, String cloudOwner) throws CloudException {
+ public void createCloudRegion(CloudSite cloudSite) throws CloudException {
createRegionInCatalogDb(cloudSite);
- createCloudRegionInAAI(cloudSite, cloudOwner);
+ createCloudRegionInAAI(cloudSite);
}
- public void updateCloudRegion(CloudSite cloudSite, String cloudOwner) throws CloudException {
+ public void updateCloudRegion(CloudSite cloudSite) throws CloudException {
updateRegionInCatalogDb(cloudSite);
}
@@ -50,18 +61,49 @@ public class CloudRestImpl {
}
}
- protected void createCloudRegionInAAI(CloudSite cloudSite, String cloudOwner) {
+ protected void createCloudRegionInAAI(CloudSite cloudSite) {
try {
- CloudRegion cloudRegion = mapCloudRegion(cloudSite, cloudOwner);
- AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION,
+ CloudRegion cloudRegion = mapCloudRegion(cloudSite);
+ Optional<Complex> complex = retrieveComplex(cloudSite);
+ if (complex.isPresent()) {
+ cloudRegion.setComplexName(complex.get().getComplexName());
+ }
+ AAIResourceUri cloudRegionURI = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION,
cloudRegion.getCloudOwner(), cloudRegion.getCloudRegionId());
- getAaiClient().createIfNotExists(uri, Optional.of(cloudRegion));
+ getAaiClient().createIfNotExists(cloudRegionURI, Optional.of(cloudRegion));
+ if (complex.isPresent()) {
+ AAIResourceUri complexURI = AAIUriFactory.createResourceUri(AAIObjectType.COMPLEX, cloudSite.getClli());
+ getAaiClient().connect(cloudRegionURI, complexURI);
+ }
+ createCloudRegionNetworkTechnologyRelationship(cloudSite, cloudRegionURI);
} catch (Exception e) {
logger.error("Error creating cloud region in AAI", e);
throw new CloudException("Error creating cloud region in AAI: " + e.getMessage(), e);
}
}
+ protected void createCloudRegionNetworkTechnologyRelationship(CloudSite cloudSite, AAIResourceUri cloudRegionURI) {
+ List<NetworkTechnologyReference> listOfNetworkTech = ctrRepo.findAllByCloudOwner(cloudSite.getCloudOwner());
+ listOfNetworkTech.stream().forEach(tech -> linkCloudAndTechnology(tech.getNetworkTechnology(), cloudRegionURI));
+ }
+
+ protected Optional<Complex> retrieveComplex(CloudSite cloudSite) {
+ AAIResourceUri complexURI = AAIUriFactory.createResourceUri(AAIObjectType.COMPLEX, cloudSite.getClli());
+ return getAaiClient().get(Complex.class, complexURI);
+ }
+
+ protected void linkCloudAndTechnology(String networkTechnologyName, AAIResourceUri cloudRegionURI) {
+ AAIPluralResourceUri technologyPluralUri = AAIUriFactory.createResourceUri(AAIObjectPlurals.NETWORK_TECHNOLOGY)
+ .queryParam("network-technology-name", networkTechnologyName);
+ Optional<NetworkTechnologies> networkTechnology =
+ getAaiClient().get(NetworkTechnologies.class, technologyPluralUri);
+ if (networkTechnology.isPresent()) {
+ AAIResourceUri networkTechnologyURI = AAIUriFactory.createResourceUri(AAIObjectType.NETWORK_TECHNOLOGY,
+ networkTechnology.get().getNetworkTechnology().get(0).getNetworkTechnologyId());
+ getAaiClient().connect(cloudRegionURI, networkTechnologyURI);
+ }
+ }
+
protected void createRegionInCatalogDb(CloudSite cloudSite) throws CloudException {
try {
CloudSite existingCloudSite = catalogDBClient.getCloudSite(cloudSite.getRegionId());
@@ -74,16 +116,22 @@ public class CloudRestImpl {
}
}
- protected CloudRegion mapCloudRegion(CloudSite cloudSite, String cloudOwner) {
+ protected CloudRegion mapCloudRegion(CloudSite cloudSite) {
CloudRegion region = new CloudRegion();
- region.setCloudOwner(cloudOwner);
+ region.setCloudOwner(cloudSite.getCloudOwner());
region.setCloudRegionId(cloudSite.getRegionId());
region.setCloudRegionVersion(cloudSite.getCloudVersion());
region.setOwnerDefinedType("cLCP");
+ region.setCloudType("openstack");
+ MavenLikeVersioning cloudVersion = new MavenLikeVersioning();
+ cloudVersion.setVersion(cloudSite.getCloudVersion());
+ if (cloudVersion.isMoreRecentThan("3.0")) {
+ region.setCloudZone(cloudSite.getRegionId().substring(0, cloudSite.getRegionId().length() - 1));
+ } else {
+ region.setCloudZone(cloudSite.getRegionId());
+ }
region.setOrchestrationDisabled(false);
- region.setComplexName("NA");
region.setInMaint(false);
- region.setCloudType("openstack");
return region;
}
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
index 32e88d8cad..60c5a0ca2a 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
@@ -33,6 +33,7 @@ import java.util.Optional;
import javax.jws.WebService;
import javax.xml.ws.Holder;
import org.apache.commons.collections.CollectionUtils;
+import org.onap.logging.filter.base.ErrorCode;
import org.onap.so.adapters.vnf.exceptions.VnfException;
import org.onap.so.adapters.vnf.exceptions.VnfNotFound;
import org.onap.so.client.aai.AAIResourcesClient;
@@ -53,7 +54,6 @@ import org.onap.so.entity.MsoRequest;
import org.onap.so.heatbridge.HeatBridgeApi;
import org.onap.so.heatbridge.HeatBridgeException;
import org.onap.so.heatbridge.HeatBridgeImpl;
-import org.onap.logging.filter.base.ErrorCode;
import org.onap.so.logger.LoggingAnchor;
import org.onap.so.logger.MessageEnum;
import org.onap.so.openstack.beans.HeatStatus;
@@ -1052,9 +1052,10 @@ public class MsoVnfAdapterImpl implements MsoVnfAdapter {
heatStack = msoHeatUtils.createStack(cloudSiteId, cloudOwner, tenantId, vfModuleName, null,
template, goldenInputs, true, heatTemplate.getTimeoutMinutes(), newEnvironmentString,
nestedTemplatesChecked, heatFilesObjects, backout.booleanValue(), failIfExists);
-
- msoHeatUtils.updateResourceStatus(msoRequest.getRequestId(),
- heatStack.isOperationPerformed() ? VF_EXIST_STATUS_MESSAGE : VF_CREATED_STATUS_MESSAGE);
+ if (msoRequest.getRequestId() != null) {
+ msoHeatUtils.updateResourceStatus(msoRequest.getRequestId(),
+ heatStack.isOperationPerformed() ? VF_EXIST_STATUS_MESSAGE : VF_CREATED_STATUS_MESSAGE);
+ }
} else {
throw new MsoHeatNotFoundException();
}
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/cloudregion/CloudRegionRestImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/cloudregion/CloudRegionRestImplTest.java
index 9c62c286ac..2df56ede10 100644
--- a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/cloudregion/CloudRegionRestImplTest.java
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/adapters/cloudregion/CloudRegionRestImplTest.java
@@ -23,6 +23,7 @@ import org.onap.so.client.aai.entities.uri.AAIResourceUri;
import org.onap.so.client.aai.entities.uri.AAIUriFactory;
import org.onap.so.db.catalog.beans.CloudSite;
import org.onap.so.db.catalog.client.CatalogDbClient;
+import org.onap.so.db.catalog.data.repository.NetworkTechnologyReferenceRepository;
@RunWith(MockitoJUnitRunner.class)
@@ -38,6 +39,9 @@ public class CloudRegionRestImplTest {
@Mock
private AAIResourcesClient aaiResClientMock;
+ @Mock
+ private NetworkTechnologyReferenceRepository ntRepoMock;
+
private CloudSite cloudSite = new CloudSite();
private CloudRegion testCloudRegion = new CloudRegion();
@@ -46,30 +50,52 @@ public class CloudRegionRestImplTest {
public void setup() {
cloudSite.setCloudVersion("1.0");
cloudSite.setRegionId("region1");
+ cloudSite.setCloudOwner("bob");
Mockito.doReturn(aaiResClientMock).when(cloudRestImpl).getAaiClient();
testCloudRegion.setCloudOwner("bob");
testCloudRegion.setCloudRegionId("region1");
testCloudRegion.setCloudRegionVersion("1.0");
testCloudRegion.setInMaint(false);
testCloudRegion.setOrchestrationDisabled(false);
- testCloudRegion.setComplexName("NA");
testCloudRegion.setCloudRegionVersion("1.0");
testCloudRegion.setOwnerDefinedType("cLCP");
testCloudRegion.setCloudType("openstack");
+ testCloudRegion.setCloudZone("region1");
}
@Test
public void mapCloudRegionTest() {
- CloudRegion mappedRegion = cloudRestImpl.mapCloudRegion(cloudSite, "bob");
+ CloudRegion mappedRegion = cloudRestImpl.mapCloudRegion(cloudSite);
assertThat(mappedRegion, sameBeanAs(testCloudRegion));
}
+
+ @Test
+ public void mapCloudRegionVersionGreaterThan3Test() {
+ CloudSite cloudSite2 = new CloudSite();
+ cloudSite2.setCloudVersion("3.0.1");
+ cloudSite2.setRegionId("region1");
+ cloudSite2.setCloudOwner("bob");
+
+ CloudRegion mappedRegion = cloudRestImpl.mapCloudRegion(cloudSite2);
+ CloudRegion testRegion2 = new CloudRegion();
+ testRegion2.setCloudOwner("bob");
+ testRegion2.setCloudRegionId("region1");
+ testRegion2.setCloudRegionVersion("3.0.1");
+ testRegion2.setInMaint(false);
+ testRegion2.setOrchestrationDisabled(false);
+ testRegion2.setOwnerDefinedType("cLCP");
+ testRegion2.setCloudType("openstack");
+ testRegion2.setCloudZone("region");
+ assertThat(mappedRegion, sameBeanAs(testRegion2));
+ }
+
@Test
public void createCloudRegionTest() {
when(catalogDbClientMock.getCloudSite("region1")).thenReturn(null);
when(catalogDbClientMock.postCloudSite(cloudSite)).thenReturn(cloudSite);
AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.CLOUD_REGION, "bob", "region1");
- cloudRestImpl.createCloudRegion(cloudSite, "bob");
+ cloudRestImpl.createCloudRegion(cloudSite);
ArgumentCaptor<AAIResourceUri> actualURI = ArgumentCaptor.forClass(AAIResourceUri.class);
ArgumentCaptor<Optional<Object>> actualCloudRegion = ArgumentCaptor.forClass(Optional.class);
verify(catalogDbClientMock, times(1)).getCloudSite("region1");
@@ -82,7 +108,7 @@ public class CloudRegionRestImplTest {
@Test
public void updateCloudRegionTest() {
when(catalogDbClientMock.updateCloudSite(cloudSite)).thenReturn(cloudSite);
- cloudRestImpl.updateCloudRegion(cloudSite, "bob");
+ cloudRestImpl.updateCloudRegion(cloudSite);
verify(catalogDbClientMock, times(1)).updateCloudSite(cloudSite);
}
diff --git a/adapters/mso-requests-db-adapter/src/main/resources/db/migration/V8.2__Fix_Invalid_Request_Status.sql b/adapters/mso-requests-db-adapter/src/main/resources/db/migration/V8.2__Fix_Invalid_Request_Status.sql
new file mode 100644
index 0000000000..9fee716326
--- /dev/null
+++ b/adapters/mso-requests-db-adapter/src/main/resources/db/migration/V8.2__Fix_Invalid_Request_Status.sql
@@ -0,0 +1,4 @@
+USE `requestdb`;
+
+UPDATE infra_active_requests SET request_status='COMPLETE' where request_status = 'COMPLETED';
+UPDATE archived_infra_requests SET request_status='COMPLETE' where request_status = 'COMPLETED'; \ No newline at end of file
diff --git a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/CompleteMsoProcess.groovy b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/CompleteMsoProcess.groovy
index 48a8e60095..ff628346b5 100644
--- a/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/CompleteMsoProcess.groovy
+++ b/bpmn/MSOCommonBPMN/src/main/groovy/org/onap/so/bpmn/common/scripts/CompleteMsoProcess.groovy
@@ -89,7 +89,7 @@ public class CompleteMsoProcess extends AbstractServiceTaskProcessor {
}
infraRequest.setLastModifiedBy("BPMN")
infraRequest.setStatusMessage(statusMessage)
- infraRequest.setRequestStatus("COMPLETED")
+ infraRequest.setRequestStatus("COMPLETE")
infraRequest.setProgress(100)
if(utils.nodeExists(xml, "vnfId")){
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSDNCNetworkResource.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSDNCNetworkResource.groovy
index 8b9726c2b7..7d1bc4c779 100644
--- a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSDNCNetworkResource.groovy
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/CreateSDNCNetworkResource.groovy
@@ -127,11 +127,7 @@ public class CreateSDNCNetworkResource extends AbstractServiceTaskProcessor {
String key = iterator.next()
HashMap<String, String> hashMap = new HashMap()
hashMap.put("name", key)
- if(jsonObject.get(key)==null){
- hashMap.put("value", "")
- }else{
- hashMap.put("value", jsonObject.get(key))
- }
+ hashMap.put("value", jsonObject.get(key))
paramList.add(hashMap)
}
Map<String, List<Map<String, Object>>> paramMap = new HashMap()
@@ -260,6 +256,17 @@ public class CreateSDNCNetworkResource extends AbstractServiceTaskProcessor {
break
+ case ~/[\w\s\W]*UNI[\w\s\W]*/ :
+ def resourceInput = resourceInputObj.getResourceParameters()
+ String incomingRequest = resourceInputObj.getRequestsInputs()
+ String serviceParameters = JsonUtils.getJsonValue(incomingRequest, "service.parameters")
+ String requestInputs = JsonUtils.getJsonValue(serviceParameters, "requestInputs")
+ JSONObject inputParameters = new JSONObject(requestInputs)
+ String uResourceInput = jsonUtil.addJsonValue(resourceInput, "requestInputs.service-name", inputParameters.get("name"))
+ resourceInputObj.setResourceParameters(uResourceInput)
+ execution.setVariable(Prefix + "resourceInput", resourceInputObj.toString())
+ break
+
case ~/[\w\s\W]*sdwanvpnattachment[\w\s\W]*/ :
case ~/[\w\s\W]*sotnvpnattachment[\w\s\W]*/ :
case ~/[\w\s\W]*SOTN-Attachment[\w\s\W]*/ :
@@ -363,7 +370,7 @@ public class CreateSDNCNetworkResource extends AbstractServiceTaskProcessor {
<sdncadapter:MsoAction>opticalservice</sdncadapter:MsoAction>
</sdncadapter:RequestHeader>
<sdncadapterworkflow:SDNCRequestData>
- <request-id>${msoUtils.xmlEscape(hdrRequestId)}</request-id>
+ <request-id>${msoUtils.xmlEscape(serviceInstanceId)}</request-id>
<global-customer-id>${msoUtils.xmlEscape(globalCustomerId)}</global-customer-id>
<service-type>${msoUtils.xmlEscape(serviceType)}</service-type>
<notification-url>sdncCallback</notification-url>
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DeleteSDNCNetworkResource.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DeleteSDNCNetworkResource.groovy
index 61b1250522..cdc242dbd8 100644
--- a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DeleteSDNCNetworkResource.groovy
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DeleteSDNCNetworkResource.groovy
@@ -221,6 +221,30 @@ public class DeleteSDNCNetworkResource extends AbstractServiceTaskProcessor {
switch (modelType) {
case "VNF":
+ if(modelName.contains("UNI") && "MDONS_OTN".equals(serviceType)){
+ String serviceInstanceName = resourceInputObj.getResourceInstanceName()
+ sdncTopologyDeleteRequest = """<aetgt:SDNCAdapterWorkflowRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
+ xmlns:sdncadapter="http://org.onap.so/workflow/sdnc/adapter/schema/v1"
+ xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
+ <sdncadapter:RequestHeader>
+ <sdncadapter:RequestId>${MsoUtils.xmlEscape(hdrRequestId)}</sdncadapter:RequestId>
+ <sdncadapter:SvcInstanceId>${MsoUtils.xmlEscape(serviceInstanceId)}</sdncadapter:SvcInstanceId>
+ <sdncadapter:SvcAction>${MsoUtils.xmlEscape(sdnc_svcAction)}</sdncadapter:SvcAction>
+ <sdncadapter:SvcOperation>optical-service-delete</sdncadapter:SvcOperation>
+ <sdncadapter:CallbackUrl>sdncCallback</sdncadapter:CallbackUrl>
+ <sdncadapter:MsoAction>opticalservice</sdncadapter:MsoAction>
+ </sdncadapter:RequestHeader>
+ <sdncadapterworkflow:SDNCRequestData>
+ <request-id>${msoUtils.xmlEscape(serviceInstanceId)}</request-id>
+ <payload>
+ <param>
+ <name>service-name</name>
+ <value>${msoUtils.xmlEscape(serviceInstanceName)}</value>
+ </param>
+ </payload>
+ </sdncadapterworkflow:SDNCRequestData>
+ </aetgt:SDNCAdapterWorkflowRequest>""".trim()
+ } else{
sdncTopologyDeleteRequest = """<aetgt:SDNCAdapterWorkflowRequest xmlns:aetgt="http://org.onap/so/workflow/schema/v1"
xmlns:sdncadapter="http://org.onap.so/workflow/sdnc/adapter/schema/v1"
xmlns:sdncadapterworkflow="http://org.onap/so/workflow/schema/v1">
@@ -275,6 +299,7 @@ public class DeleteSDNCNetworkResource extends AbstractServiceTaskProcessor {
</vnf-request-input>
</sdncadapterworkflow:SDNCRequestData>
</aetgt:SDNCAdapterWorkflowRequest>""".trim()
+ }
break
case "GROUP" :
//When a new resource creation request reaches SO, the parent resources information needs to be provided
diff --git a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoDeleteE2EServiceInstance.groovy b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoDeleteE2EServiceInstance.groovy
index a24bc4411e..35af3d34d6 100644
--- a/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoDeleteE2EServiceInstance.groovy
+++ b/bpmn/so-bpmn-infrastructure-common/src/main/groovy/org/onap/so/bpmn/infrastructure/scripts/DoDeleteE2EServiceInstance.groovy
@@ -450,6 +450,16 @@ public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
execution.setVariable("serviceModelInfo", serviceDecomposition.getModelInfo())
List<Resource> deleteResourceList = serviceDecomposition.getServiceResources()
+ if (serviceDecomposition.getServiceType().equals("MDONS_OTN")){
+ for (Resource resource : deleteResourceList) {
+ String serviceName = execution.getVariable("serviceInstanceName")
+ String serviceInstanceId = execution.getVariable("serviceInstanceId")
+ resource.setResourceId(serviceInstanceId)
+ resource.setResourceInstanceName(serviceName)
+ def delMap = new ImmutablePair(resource, null)
+ deleteRealResourceList.add(delMap)
+ }
+ } else{
String serviceRelationShip = execution.getVariable("serviceRelationShip")
def jsonSlurper = new JsonSlurper()
def jsonOutput = new JsonOutput()
@@ -492,6 +502,7 @@ public class DoDeleteE2EServiceInstance extends AbstractServiceTaskProcessor {
}
}
}
+ }
// only delete real existing resources
execution.setVariable("deleteResourceList", deleteRealResourceList)
diff --git a/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoDeleteE2EServiceInstance.bpmn b/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoDeleteE2EServiceInstance.bpmn
index 1149cc9ea9..85fe3b4b29 100644
--- a/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoDeleteE2EServiceInstance.bpmn
+++ b/bpmn/so-bpmn-infrastructure-flows/src/main/resources/subprocess/DoDeleteE2EServiceInstance.bpmn
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
-<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.1.0">
+<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:camunda="http://camunda.org/schema/1.0/bpmn" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="Definitions_1" targetNamespace="http://bpmn.io/schema/bpmn" exporter="Camunda Modeler" exporterVersion="3.4.1">
<bpmn:process id="DoDeleteE2EServiceInstance" name="All Resources Deleted" isExecutable="true">
<bpmn:startEvent id="StartEvent_0212h2r" name="Start Flow">
<bpmn:outgoing>SequenceFlow_0vz7cd9</bpmn:outgoing>
@@ -131,6 +131,7 @@ dcsi.postDecomposeService(execution)</bpmn:script>
<camunda:in source="operationType" target="operationType" />
<camunda:in source="operationId" target="operationId" />
<camunda:in source="serviceDecomposition" target="serviceDecomposition" />
+ <camunda:in source="serviceInstanceName" target="serviceInstanceName" />
</bpmn:extensionElements>
<bpmn:incoming>SequenceFlow_1j08ko3</bpmn:incoming>
<bpmn:outgoing>SequenceFlow_1cevtpy</bpmn:outgoing>
diff --git a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasks.java b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasks.java
index d9f5e65ba3..cdba6e0e2f 100644
--- a/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasks.java
+++ b/bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasks.java
@@ -173,7 +173,7 @@ public class ManualHandlingTasks {
taskVariables.put(TASK_VARIABLE_DESCRIPTION, description);
TaskService taskService = execution.getProcessEngineServices().getTaskService();
- taskService.setVariables(taskId, taskVariables);
+ taskService.setVariablesLocal(taskId, taskVariables);
logger.debug("successfully created fallout task: " + taskId);
} catch (BpmnError e) {
logger.debug(BPMN_EXCEPTION + e.getMessage());
@@ -223,7 +223,7 @@ public class ManualHandlingTasks {
taskVariables.put(TASK_VARIABLE_VALID_RESPONSES, validResponses);
TaskService taskService = execution.getProcessEngineServices().getTaskService();
- taskService.setVariables(taskId, taskVariables);
+ taskService.setVariablesLocal(taskId, taskVariables);
logger.debug("successfully created pause task: " + taskId);
} catch (BpmnError e) {
logger.debug(BPMN_EXCEPTION + e.getMessage());
diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasksTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasksTest.java
index b6dcd96534..e3bbd11cc4 100644
--- a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasksTest.java
+++ b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/manualhandling/tasks/ManualHandlingTasksTest.java
@@ -100,7 +100,7 @@ public class ManualHandlingTasksTest extends BaseTaskTest {
when(mockExecution.getProcessEngineServices()).thenReturn(processEngineServices);
when(processEngineServices.getTaskService()).thenReturn(taskService);
manualHandlingTasks.setFalloutTaskVariables(task);
- verify(taskService, times(1)).setVariables(any(String.class), any(Map.class));
+ verify(taskService, times(1)).setVariablesLocal(any(String.class), any(Map.class));
}
@Test
@@ -110,7 +110,7 @@ public class ManualHandlingTasksTest extends BaseTaskTest {
when(mockExecution.getProcessEngineServices()).thenReturn(processEngineServices);
when(processEngineServices.getTaskService()).thenReturn(taskService);
manualHandlingTasks.setPauseTaskVariables(task);
- verify(taskService, times(1)).setVariables(any(String.class), any(Map.class));
+ verify(taskService, times(1)).setVariablesLocal(any(String.class), any(Map.class));
}
@Test
diff --git a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/CloudSite.java b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/CloudSite.java
index deaa2a3221..0d7fe7d38f 100644
--- a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/CloudSite.java
+++ b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/CloudSite.java
@@ -93,6 +93,11 @@ public class CloudSite {
@Column(name = "CLOUDIFY_ID")
private String cloudifyId;
+ @JsonProperty("cloud_owner")
+ @BusinessKey
+ @Column(name = "CLOUD_OWNER")
+ private String cloudOwner;
+
// Derived property (set by CloudConfig loader based on identityServiceId)
@BusinessKey
@OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@@ -266,12 +271,20 @@ public class CloudSite {
this.identityServiceId = identityServiceId;
}
+ public String getCloudOwner() {
+ return cloudOwner;
+ }
+
+ public void setCloudOwner(String cloudOwner) {
+ this.cloudOwner = cloudOwner;
+ }
+
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE).append("regionId", getRegionId())
.append("identityServiceId", getIdentityServiceId()).append("cloudVersion", getCloudVersion())
.append("clli", getClli()).append("cloudifyId", getCloudifyId()).append("platform", getPlatform())
- .append("orchestrator", getOrchestrator()).toString();
+ .append("orchestrator", getOrchestrator()).append("cloud-owner", getCloudOwner()).toString();
}
@Override
diff --git a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/NetworkTechnologyReference.java b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/NetworkTechnologyReference.java
new file mode 100644
index 0000000000..1f19dcc1dd
--- /dev/null
+++ b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/beans/NetworkTechnologyReference.java
@@ -0,0 +1,101 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2019 Tech Mahindra
+ * ================================================================================
+ * 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.onap.so.db.catalog.beans;
+
+import java.io.Serializable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+import org.apache.commons.lang3.builder.EqualsBuilder;
+import org.apache.commons.lang3.builder.HashCodeBuilder;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import com.openpojo.business.annotation.BusinessKey;
+
+@Entity
+@Table(name = "network_technology_reference")
+public class NetworkTechnologyReference implements Serializable {
+
+ private static final long serialVersionUID = 1L;
+
+ @Id
+ @Column(name = "ID", nullable = false, updatable = false)
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ @BusinessKey
+ @Column(name = "cloud_owner")
+ private String cloudOwner;
+
+ @BusinessKey
+ @Column(name = "network_technology")
+ private String networkTechnology;
+
+ @Override
+ public String toString() {
+ return new ToStringBuilder(this).append("id", id).append("cloudOwner", cloudOwner)
+ .append("networkTechnology", networkTechnology).toString();
+ }
+
+ @Override
+ public boolean equals(final Object other) {
+ if (!(other instanceof NetworkTechnologyReference)) {
+ return false;
+ }
+ NetworkTechnologyReference castOther = (NetworkTechnologyReference) other;
+ return new EqualsBuilder().append(cloudOwner, castOther.cloudOwner)
+ .append(networkTechnology, castOther.networkTechnology).isEquals();
+ }
+
+ @Override
+ public int hashCode() {
+ return new HashCodeBuilder().append(cloudOwner).append(networkTechnology).toHashCode();
+ }
+
+ public static long getSerialversionuid() {
+ return serialVersionUID;
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getCloudOwner() {
+ return cloudOwner;
+ }
+
+ public void setCloudOwner(String cloudOwner) {
+ this.cloudOwner = cloudOwner;
+ }
+
+ public String getNetworkTechnology() {
+ return networkTechnology;
+ }
+
+ public void setNetworkTechnology(String networkTechnology) {
+ this.networkTechnology = networkTechnology;
+ }
+
+
+
+}
diff --git a/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/NetworkTechnologyReferenceRepository.java b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/NetworkTechnologyReferenceRepository.java
new file mode 100644
index 0000000000..0b7065490b
--- /dev/null
+++ b/mso-catalog-db/src/main/java/org/onap/so/db/catalog/data/repository/NetworkTechnologyReferenceRepository.java
@@ -0,0 +1,32 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2019 Tech Mahindra
+ * ================================================================================
+ * 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.onap.so.db.catalog.data.repository;
+
+
+import java.util.List;
+import org.onap.so.db.catalog.beans.NetworkTechnologyReference;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+
+public interface NetworkTechnologyReferenceRepository extends JpaRepository<NetworkTechnologyReference, Integer> {
+
+ List<NetworkTechnologyReference> findAllByCloudOwner(String cloudOwner);
+}
diff --git a/mso-catalog-db/src/test/resources/data.sql b/mso-catalog-db/src/test/resources/data.sql
index 0852aa026d..b38d4d9376 100644
--- a/mso-catalog-db/src/test/resources/data.sql
+++ b/mso-catalog-db/src/test/resources/data.sql
@@ -683,7 +683,7 @@ INSERT INTO `cloudify_managers` (`ID`, `CLOUDIFY_URL`, `USERNAME`, `PASSWORD`, `
INSERT INTO `identity_services` (`ID`, `IDENTITY_URL`, `MSO_ID`, `MSO_PASS`, `PROJECT_DOMAIN_NAME`, `USER_DOMAIN_NAME`, `ADMIN_TENANT`, `MEMBER_ROLE`, `TENANT_METADATA`, `IDENTITY_SERVER_TYPE`, `IDENTITY_AUTHENTICATION_TYPE`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`) VALUES ('MTN13', 'http://localhost:28090/v2.0', 'm93945', '93937EA01B94A10A49279D4572B48369', NULL, NULL, 'admin', 'admin', 1, 'KEYSTONE', 'USERNAME_PASSWORD', 'MSO_USER', '2018-07-17 14:02:33', '2018-07-17 14:02:33');
-INSERT INTO `cloud_sites` (`ID`, `REGION_ID`, `IDENTITY_SERVICE_ID`, `CLOUD_VERSION`, `CLLI`, `CLOUDIFY_ID`, `PLATFORM`, `ORCHESTRATOR`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`, `SUPPORT_FABRIC`) VALUES ('mtn13', 'mtn13', 'MTN13', '2.5', 'MDT13', 'mtn13', NULL, 'orchestrator', 'MSO_USER', '2018-07-17 14:06:28', '2018-07-17 14:06:28', 1);
+INSERT INTO `cloud_sites` (`ID`, `REGION_ID`, `IDENTITY_SERVICE_ID`, `CLOUD_VERSION`, `CLLI`, `CLOUDIFY_ID`, `PLATFORM`, `ORCHESTRATOR`, `LAST_UPDATED_BY`, `CREATION_TIMESTAMP`, `UPDATE_TIMESTAMP`, `SUPPORT_FABRIC`,`CLOUD_OWNER`) VALUES ('mtn13', 'mtn13', 'MTN13', '2.5', 'MDT13', 'mtn13', NULL, 'orchestrator', 'MSO_USER', '2018-07-17 14:06:28', '2018-07-17 14:06:28', 1,'cloudOwner');
INSERT INTO `controller_selection_reference` (`VNF_TYPE`, `CONTROLLER_NAME`, `ACTION_CATEGORY`) VALUES
('vLoadBalancerMS/vLoadBalancerMS 0', 'APPC', 'ConfigScaleOut'),
diff --git a/mso-catalog-db/src/test/resources/schema.sql b/mso-catalog-db/src/test/resources/schema.sql
index 02491705bc..0d49903e51 100644
--- a/mso-catalog-db/src/test/resources/schema.sql
+++ b/mso-catalog-db/src/test/resources/schema.sql
@@ -121,6 +121,7 @@ CREATE TABLE `cloud_sites` (
`CREATION_TIMESTAMP` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`UPDATE_TIMESTAMP` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
`SUPPORT_FABRIC` bit(1) NOT NULL DEFAULT 1,
+ `CLOUD_OWNER` varchar(225) NOT NULL,
PRIMARY KEY (`ID`),
KEY `FK_cloud_sites_identity_services` (`IDENTITY_SERVICE_ID`),
CONSTRAINT `FK_cloud_sites_identity_services` FOREIGN KEY (`IDENTITY_SERVICE_ID`) REFERENCES `identity_services` (`ID`)