From 5a34dbbd091db590a9a38e5398140933ae9ed639 Mon Sep 17 00:00:00 2001 From: Jennie Jia Date: Tue, 11 Sep 2018 15:06:39 +0000 Subject: Update API and common model mapping Issue-ID: LOG-646 Change-Id: Ie56d3f697abbafecf9c2d9f73fa52bee1833a469 Signed-off-by: Jennie Jia --- .../pomba/contextbuilder/aai/AAIConfiguration.java | 8 - .../pomba/contextbuilder/aai/datatype/Vserver.java | 203 +++++++++++ .../contextbuilder/aai/service/SpringService.java | 2 +- .../aai/service/SpringServiceImpl.java | 11 +- .../contextbuilder/aai/service/rs/RestService.java | 8 +- .../aai/service/rs/RestServiceImpl.java | 11 +- .../pomba/contextbuilder/aai/util/RestUtil.java | 401 ++++++++++++++++----- 7 files changed, 530 insertions(+), 114 deletions(-) create mode 100644 src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java (limited to 'src/main') diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java b/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java index 7befdc9..22f7b5e 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java @@ -55,10 +55,6 @@ public class AAIConfiguration { @Value("${aai.readTimeout}") private Integer readTimeout; - @Autowired - @Value("${aai.serviceInstancePath}") - private String serviceInstancePath; - @Autowired @Value("${http.userId}") private String httpUserId; @@ -99,10 +95,6 @@ public class AAIConfiguration { } - @Bean(name="aaiServiceInstancePath") - public String getserviceInstancePathL() { - return serviceInstancePath; - } @Value("${aai.searchNodeQuery}") private String searchNodeQuery; diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java new file mode 100644 index 0000000..368dd90 --- /dev/null +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java @@ -0,0 +1,203 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * 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.pomba.contextbuilder.aai.datatype; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.onap.pomba.contextbuilder.aai.exception.AuditError; +import org.onap.pomba.contextbuilder.aai.exception.AuditException; + +public class Vserver { + + @SerializedName("vserver-id") + @Expose + private String vserverId; + @SerializedName("vserver-name") + @Expose + private String vserverName; + @SerializedName("vserver-name2") + @Expose + private String vserverName2; + @SerializedName("prov-status") + @Expose + private String provStatus; + @SerializedName("vserver-selflink") + @Expose + private String vserverSelflink; + @SerializedName("in-maint") + @Expose + private Boolean inMaint; + @SerializedName("is-closed-loop-disabled") + @Expose + private Boolean isClosedLoopDisabled; + @SerializedName("resource-version") + @Expose + private String resourceVersion; + @SerializedName("relationship-list") + @Expose + private RelationshipList relationshipList; + + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + public String toJson() { + return gson.toJson(this); + } + + public static Vserver fromJson(String payload) throws AuditException { + try { + if (payload == null || payload.isEmpty()) { + throw new AuditException("Empty Json response"); + } + return gson.fromJson(payload, Vserver.class); + } catch (Exception ex) { + throw new AuditException(AuditError.JSON_READER_PARSE_ERROR, ex); + } + } + + /** + * No args constructor for use in serialization + * + */ + public Vserver() { + } + + /** + * + * @param relationshipList + * @param provStatus + * @param inMaint + * @param vserverName2 + * @param resourceVersion + * @param vserverSelflink + * @param vserverName + * @param vserverId + * @param isClosedLoopDisabled + */ + public Vserver(String vserverId, String vserverName, String vserverName2, String provStatus, String vserverSelflink, Boolean inMaint, Boolean isClosedLoopDisabled, String resourceVersion, RelationshipList relationshipList) { + super(); + this.vserverId = vserverId; + this.vserverName = vserverName; + this.vserverName2 = vserverName2; + this.provStatus = provStatus; + this.vserverSelflink = vserverSelflink; + this.inMaint = inMaint; + this.isClosedLoopDisabled = isClosedLoopDisabled; + this.resourceVersion = resourceVersion; + this.relationshipList = relationshipList; + } + + public String getVserverId() { + return vserverId; + } + + public void setVserverId(String vserverId) { + this.vserverId = vserverId; + } + + public String getVserverName() { + return vserverName; + } + + public void setVserverName(String vserverName) { + this.vserverName = vserverName; + } + + public String getVserverName2() { + return vserverName2; + } + + public void setVserverName2(String vserverName2) { + this.vserverName2 = vserverName2; + } + + public String getProvStatus() { + return provStatus; + } + + public void setProvStatus(String provStatus) { + this.provStatus = provStatus; + } + + public String getVserverSelflink() { + return vserverSelflink; + } + + public void setVserverSelflink(String vserverSelflink) { + this.vserverSelflink = vserverSelflink; + } + + public Boolean getInMaint() { + return inMaint; + } + + public void setInMaint(Boolean inMaint) { + this.inMaint = inMaint; + } + + public Boolean getIsClosedLoopDisabled() { + return isClosedLoopDisabled; + } + + public void setIsClosedLoopDisabled(Boolean isClosedLoopDisabled) { + this.isClosedLoopDisabled = isClosedLoopDisabled; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public RelationshipList getRelationshipList() { + return relationshipList; + } + + public void setRelationshipList(RelationshipList relationshipList) { + this.relationshipList = relationshipList; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("vserverId", vserverId).append("vserverName", vserverName).append("vserverName2", vserverName2).append("provStatus", provStatus).append("vserverSelflink", vserverSelflink).append("inMaint", inMaint).append("isClosedLoopDisabled", isClosedLoopDisabled).append("resourceVersion", resourceVersion).append("relationshipList", relationshipList).toString(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder().append(relationshipList).append(provStatus).append(inMaint).append(vserverName2).append(resourceVersion).append(vserverSelflink).append(vserverName).append(vserverId).append(isClosedLoopDisabled).toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if ((other instanceof Vserver) == false) { + return false; + } + Vserver rhs = ((Vserver) other); + return new EqualsBuilder().append(relationshipList, rhs.relationshipList).append(provStatus, rhs.provStatus).append(inMaint, rhs.inMaint).append(vserverName2, rhs.vserverName2).append(resourceVersion, rhs.resourceVersion).append(vserverSelflink, rhs.vserverSelflink).append(vserverName, rhs.vserverName).append(vserverId, rhs.vserverId).append(isClosedLoopDisabled, rhs.isClosedLoopDisabled).isEquals(); + } + +} diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringService.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringService.java index aa28e2b..59ee36d 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringService.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringService.java @@ -23,5 +23,5 @@ import org.onap.pomba.contextbuilder.aai.exception.AuditException; public interface SpringService { - public ModelContext getContext(String serviceInstanceId, String modelVersionId, String modelInvariantId, String serviceType, String customerId, String transactionId) throws AuditException; + public ModelContext getContext(String serviceInstanceId, String modelVersionId, String modelInvariantId, String transactionId) throws AuditException; } diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java index 2ec49f3..bce3a2e 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java @@ -35,8 +35,7 @@ public class SpringServiceImpl implements SpringService { private RestClient aaiClient; @Autowired private String aaiBaseUrl; - @Autowired - private String aaiServiceInstancePath; + @Autowired private String aaiBasicAuthorization; @Autowired @@ -46,18 +45,16 @@ public class SpringServiceImpl implements SpringService { // needed for instantiation } - @Override - public ModelContext getContext(String serviceInstanceId, String modelVersionId, String modelInvariantId, String serviceType, String customerId, String tranId) throws AuditException { + public ModelContext getContext(String serviceInstanceId, String modelVersionId, String modelInvariantId, String tranId) throws AuditException { - String url = "serviceInstanceId=" + serviceInstanceId + " modelVersion="+modelVersionId + - " modelInvariantId="+ modelInvariantId + " serviceType="+serviceType + " customerId="+ customerId; + String url = "serviceInstanceId=" + serviceInstanceId + " modelVersion="+modelVersionId + " modelInvariantId="+ modelInvariantId ; log.info(LogMessages.AAI_CONTEXT_BUILDER_URL, url); ModelContext context = null; // Retrieve the service instance information from AAI try { - context= RestUtil.retrieveAAIModelData(aaiClient, aaiBaseUrl, aaiPathToSearchNodeQuery, aaiServiceInstancePath, tranId, serviceInstanceId, modelVersionId, modelInvariantId, serviceType, customerId,aaiBasicAuthorization); + context= RestUtil.retrieveAAIModelData(aaiClient, aaiBaseUrl, aaiPathToSearchNodeQuery, tranId, serviceInstanceId, modelVersionId, modelInvariantId, aaiBasicAuthorization); } catch (AuditException ae) { throw ae; } catch (Exception e) { diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestService.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestService.java index dcc3382..22efa35 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestService.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestService.java @@ -44,19 +44,17 @@ public interface RestService { value = "Respond AAIContext Model Data", notes = "Returns a JSON object which represents the AAIConetxt model data", response = GenericResponse.class - ) + ) @ApiResponses( value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 400, message = "Bad Request"), @ApiResponse(code = 404, message = "Service not available"), @ApiResponse(code = 500, message = "Unexpected Runtime error") - }) + }) public Response getContext(@Context HttpHeaders headers, @QueryParam("serviceInstanceId") String serviceInstanceId, @QueryParam("modelVersionId") String modelVersionId, - @QueryParam("modelInvariantId") String modelInvariantId, - @QueryParam("serviceType") String serviceType, - @QueryParam("customerId") String customerId + @QueryParam("modelInvariantId") String modelInvariantId ); } \ No newline at end of file diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java index 6fc2c8a..824e251 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java @@ -43,10 +43,9 @@ public class RestServiceImpl implements RestService { private String httpBasicAuthorization; @Override - public Response getContext(HttpHeaders headers, String serviceInstanceId, String modelVersionId, String modelInvariantId, String serviceType, String customerId) { + public Response getContext(HttpHeaders headers, String serviceInstanceId, String modelVersionId, String modelInvariantId) { - String url = "serviceInstanceId=" + serviceInstanceId + " modelVersion="+modelVersionId + - " modelInvariantId="+ modelInvariantId + " serviceType="+serviceType + " customerId="+ customerId; + String url = "serviceInstanceId=" + serviceInstanceId + " modelVersion="+modelVersionId + " modelInvariantId="+ modelInvariantId; if(log.isDebugEnabled()) { log.debug(LogMessages.AAI_CONTEXT_BUILDER_URL, url); } @@ -60,14 +59,14 @@ public class RestServiceImpl implements RestService { try { // Do some validation on Http headers and URL parameters - RestUtil.validateBasicAuthorization(headers, httpBasicAuthorization); + RestUtil.validateBasicAuthorization(headers, httpBasicAuthorization); RestUtil.validateHeader(headers); - RestUtil.validateURL(serviceInstanceId, modelVersionId, modelInvariantId, serviceType, customerId); + RestUtil.validateURL(serviceInstanceId, modelVersionId, modelInvariantId); // Keep the same transaction id for logging purpose transactionId= RestUtil.extractTranIdHeader(headers); - aaiContext = service.getContext(serviceInstanceId, modelVersionId, modelInvariantId, serviceType, customerId, transactionId); + aaiContext = service.getContext(serviceInstanceId, modelVersionId, modelInvariantId, transactionId); if (aaiContext==null) { // Return empty JSON diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java b/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java index 905a8bc..60bbd61 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java @@ -14,9 +14,7 @@ package org.onap.pomba.contextbuilder.aai.util; - import com.sun.jersey.core.util.MultivaluedMapImpl; -import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -35,21 +33,27 @@ import org.json.JSONException; import org.json.JSONObject; import org.onap.aai.restclient.client.OperationResult; import org.onap.aai.restclient.client.RestClient; +import org.onap.pomba.common.datatypes.Attribute; +import org.onap.pomba.common.datatypes.DataQuality; import org.onap.pomba.common.datatypes.ModelContext; import org.onap.pomba.common.datatypes.Service; import org.onap.pomba.common.datatypes.VF; import org.onap.pomba.common.datatypes.VFModule; +import org.onap.pomba.common.datatypes.VM; import org.onap.pomba.common.datatypes.VNFC; import org.onap.pomba.contextbuilder.aai.common.LogMessages; +import org.onap.pomba.contextbuilder.aai.datatype.Relationship; +import org.onap.pomba.contextbuilder.aai.datatype.RelationshipList; import org.onap.pomba.contextbuilder.aai.datatype.ServiceInstance; import org.onap.pomba.contextbuilder.aai.datatype.VfModule; import org.onap.pomba.contextbuilder.aai.datatype.VnfInstance; import org.onap.pomba.contextbuilder.aai.datatype.VnfcInstance; +import org.onap.pomba.contextbuilder.aai.datatype.Vserver; import org.onap.pomba.contextbuilder.aai.exception.AuditError; import org.onap.pomba.contextbuilder.aai.exception.AuditException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; + public class RestUtil { @@ -60,8 +64,7 @@ public class RestUtil { private static final String SERVICE_INSTANCE_ID = "serviceInstanceId"; private static final String MODEL_VERSION_ID = "modelVersionId"; private static final String MODEL_INVARIANT_ID = "modelInvariantId"; - private static final String CUSTOMER_ID = "customerId"; - private static final String SERVICE_TYPE = "serviceType"; + // HTTP headers private static final String TRANSACTION_ID = "X-TransactionId"; @@ -70,10 +73,16 @@ public class RestUtil { private static final String APP_NAME = "aaiCtxBuilder"; - // Service Catalog + // Service Catalog - "related-to" private static final String CATALOG_GENERIC_VNF = "generic-vnf"; private static final String CATALOG_VNFC = "vnfc"; private static final String CATALOG_SERVICE_INSTANCE = "service-instance"; + private static final String CATALOG_VSERVER = "vserver"; + private static final String CATALOG_IMAGE = "image"; + private static final String CATALOG_PSERVER = "pserver"; + private static final String VF_MODULES = "vf-modules"; + private static final String VF_MODULE = "vf-module"; + // Relationship Json Path private static final String RELATIONSHIP_LIST = "relationship-list"; @@ -95,8 +104,8 @@ public class RestUtil { * * @throws AuditException if there is missing parameter */ - public static void validateURL(String serviceInstanceId, String modelVersionId, String modelInvariantId, - String serviceType, String customerId) throws AuditException { + public static void validateURL(String serviceInstanceId, String modelVersionId, String modelInvariantId) + throws AuditException { if (serviceInstanceId == null || serviceInstanceId.isEmpty()) { throw new AuditException(AuditError.INVALID_REQUEST_URL_MISSING_PARAMETER + SERVICE_INSTANCE_ID, @@ -112,18 +121,10 @@ public class RestUtil { Status.BAD_REQUEST); } - // serviceType - if (serviceType == null || serviceType.isEmpty()) { - throw new AuditException(AuditError.INVALID_REQUEST_URL_MISSING_PARAMETER + SERVICE_TYPE, Status.BAD_REQUEST); - } - // customerId - if (customerId == null || customerId.isEmpty()) { - throw new AuditException(AuditError.INVALID_REQUEST_URL_MISSING_PARAMETER + CUSTOMER_ID, Status.BAD_REQUEST); - } } public static void validateBasicAuthorization(HttpHeaders headers, String basicAuthorization) throws AuditException { - String authorization = null; + String authorization = null; // validation on HTTP Authorization Header authorization = headers.getRequestHeaders().getFirst(AUTHORIZATION); @@ -166,25 +167,25 @@ public class RestUtil { } /* - * Trigger external API call to AAI to retrieve Service Instance data (i.e. genericVNF and VNFC) + * Trigger external API call to AAI to collect the data in order to transform to common model + * */ - public static ModelContext retrieveAAIModelData(RestClient aaiClient, String baseURL, String aaiPathToSearchNodeQuery, String aaiServiceInstancePath, - String transactionId, String serviceInstanceId, String modelVersionId, String modelInvariantId, - String serviceType, String customerId, String aaiBasicAuthorization) throws AuditException { + public static ModelContext retrieveAAIModelData(RestClient aaiClient, String baseURL, String aaiPathToSearchNodeQuery, + String transactionId, String serviceInstanceId, String modelVersionId, String modelInvariantId, String aaiBasicAuthorization) throws AuditException { String serviceInstancePayload = null; String genericVNFPayload = null; - String vnfcPayload = null; - // Follow two variables for transform purpose List vnfLst = new ArrayList(); // List of the VNF POJO object - Map> vnfMap = new HashMap>(); // MAP the vnf-id as the - // key, and list of the vNFC - // pojo object + //Map to track multiple vnfc under the Gerneric VNF id. The key = vnf-id. The value = list of vnfc instance + Map> vnfcMap = new HashMap>(); + + //Map to track the relationship between vnf->vfmodule->verver + Map>> vnf_vfmodule_vserver_Map = new HashMap>>(); + // Obtain resource-link based on resource-type = service-Instance String resourceLink = obtainResouceLinkBasedOnServiceInstanceFromAAI(aaiClient, baseURL, aaiPathToSearchNodeQuery, serviceInstanceId, transactionId, aaiBasicAuthorization); + String url = baseURL + resourceLink; - String url = baseURL - + generateServiceInstanceURL(aaiServiceInstancePath, customerId, serviceType, serviceInstanceId); // Response from service instance API call serviceInstancePayload = getResource(aaiClient, url, aaiBasicAuthorization, transactionId, MediaType.valueOf(MediaType.APPLICATION_JSON)); @@ -200,7 +201,6 @@ public class RestUtil { log.info(LogMessages.NUMBER_OF_API_CALLS, "genericVNF", genericVNFLinkLst.size()); log.info(LogMessages.API_CALL_LIST, "genericVNF", printOutAPIList(genericVNFLinkLst)); - for (String genericVNFLink : genericVNFLinkLst) { // With latest AAI development, in order to retrieve the both generic VNF + vf_module, we can use // one API call but with depth=2 @@ -212,50 +212,121 @@ public class RestUtil { if (isEmptyJson(genericVNFPayload)) { log.info(LogMessages.NOT_FOUND, "GenericVNF with url ", genericVNFLink); } else { - // Logic to Create the Generic VNF Instance POJO object VnfInstance vnfInstance = VnfInstance.fromJson(genericVNFPayload); vnfLst.add(vnfInstance); - List vnfcLinkLst = extractRelatedLink(genericVNFPayload, CATALOG_VNFC); - log.info(LogMessages.NUMBER_OF_API_CALLS, "vnfc", vnfcLinkLst.size()); - log.info(LogMessages.API_CALL_LIST, "vnfc", printOutAPIList(vnfcLinkLst)); - - List vnfcLst = new ArrayList(); - for (String vnfcLink : vnfcLinkLst) { - String vnfcURL = baseURL + vnfcLink; - vnfcPayload = getResource(aaiClient, vnfcURL, aaiBasicAuthorization, transactionId, - MediaType.valueOf(MediaType.APPLICATION_XML)); - - if (isEmptyJson(vnfcPayload)) { - log.info(LogMessages.NOT_FOUND, "VNFC with url", vnfcLink); - } else { - // Logic to Create the VNFC POJO object - VnfcInstance vnfcInstance = VnfcInstance.fromJson(vnfcPayload); - vnfcLst.add(vnfcInstance); - } - } + // Build the vnf_vnfc relationship map + vnfcMap = buildVnfcMap(genericVNFPayload, aaiClient, baseURL, transactionId, aaiBasicAuthorization ); + + // Build vnf_vfmodule_vserver relationship map + vnf_vfmodule_vserver_Map= buildVfmoduleVserverMap(genericVNFPayload, aaiClient, baseURL, transactionId, aaiBasicAuthorization); - // Assume the vnf-id is unique as a key - vnfMap.put(vnfInstance.getVnfId(), vnfcLst); } } // Transform to common model and return - return transform(ServiceInstance.fromJson(serviceInstancePayload), vnfLst, vnfMap); + return transform(ServiceInstance.fromJson(serviceInstancePayload), vnfLst, vnfcMap, vnf_vfmodule_vserver_Map); } + /* + * The map is to track the relationship of vnf-id with multiple vnfc relationship + */ + private static Map> buildVnfcMap(String genericVNFPayload, RestClient aaiClient, String baseURL, + String transactionId, String aaiBasicAuthorization) throws AuditException { + + String vnfcPayload = null; + Map> vnfcMap = new HashMap>(); + + List vnfcLinkLst = extractRelatedLink(genericVNFPayload, CATALOG_VNFC); + log.info(LogMessages.NUMBER_OF_API_CALLS, "vnfc", vnfcLinkLst.size()); + log.info(LogMessages.API_CALL_LIST, "vnfc", printOutAPIList(vnfcLinkLst)); + + List vnfcLst = new ArrayList(); + for (String vnfcLink : vnfcLinkLst) { + String vnfcURL = baseURL + vnfcLink; + vnfcPayload = getResource(aaiClient, vnfcURL, aaiBasicAuthorization, transactionId, + MediaType.valueOf(MediaType.APPLICATION_XML)); + + if (isEmptyJson(vnfcPayload)) { + log.info(LogMessages.NOT_FOUND, "VNFC with url", vnfcLink); + } else { + // Logic to Create the VNFC POJO object + VnfcInstance vnfcInstance = VnfcInstance.fromJson(vnfcPayload); + vnfcLst.add(vnfcInstance); + } + } + // Assume the vnf-id is unique as a key + vnfcMap.put(getVnfId(genericVNFPayload), vnfcLst); + + return vnfcMap; + } + + /* + * This is a two layer map to track the relationship between vnf->vfmodule->verver + * + * The Map is to track multiple vserver under the vfModule. + * Key: combination of the model_version_id and model_invariant_id. + * Value: list of Vserver + * + * The Map>> key: vnf-id + */ + private static Map>> buildVfmoduleVserverMap(String genericVNFPayload, RestClient aaiClient, String baseURL, String transactionId, String aaiBasicAuthorization) throws AuditException { + + Map>> vnf_vfmodule_vserver_Map = new HashMap>>(); + + Map> vServerMap = new HashMap>(); + + Map> vServerRelatedLinkMap = extractRelatedLinkFromVfmodule(genericVNFPayload, CATALOG_VSERVER); + String vnfId= getVnfId(genericVNFPayload); + String vserverPayload = null; + + for(Map.Entry> entry : vServerRelatedLinkMap.entrySet()) { + + List vserverLinkLst = entry.getValue(); + log.info(LogMessages.NUMBER_OF_API_CALLS, "vserver", vserverLinkLst.size()); + log.info(LogMessages.API_CALL_LIST, "vserver", printOutAPIList(vserverLinkLst)); + + List vserverLst = new ArrayList(); + for (String vserverLink : vserverLinkLst) { + String vserverURL = baseURL + vserverLink; + vserverPayload = getResource(aaiClient, vserverURL, aaiBasicAuthorization, transactionId, + MediaType.valueOf(MediaType.APPLICATION_XML)); + + if (isEmptyJson(vserverPayload)) { + log.info(LogMessages.NOT_FOUND, "VSERVER with url", vserverURL); + } else { + // Logic to Create the Vserver POJO object + Vserver vserver = Vserver.fromJson(vserverPayload); + vserverLst.add(vserver); + } + } + + vServerMap.put(entry.getKey(), vserverLst); + } + + vnf_vfmodule_vserver_Map.put(vnfId, vServerMap); + + return vnf_vfmodule_vserver_Map; + } + + + private static String getVnfId(String genericVNFPayload) throws AuditException { + + VnfInstance vnfInstance = VnfInstance.fromJson(genericVNFPayload); + return vnfInstance.getVnfId(); + } /* * Transform AAI Representation to Common Model */ private static ModelContext transform(ServiceInstance svcInstance, List vnfLst, - Map> vnfMap) { + Map> vnfcMap, Map>> vnf_vfmodule_vserver_Map) { ModelContext context = new ModelContext(); Service service = new Service(); service.setInvariantUuid(svcInstance.getModelInvariantId()); service.setName(svcInstance.getServiceInstanceName()); service.setUuid(svcInstance.getModelVersionId()); - + service.setDataQuality(DataQuality.ok()); List vfLst = new ArrayList(); for (VnfInstance vnf : vnfLst) { @@ -264,12 +335,13 @@ public class RestUtil { vf.setName(vnf.getVnfName()); vf.setUuid(vnf.getModelVersionId()); vf.setType(vnf.getVnfType()); - vf.setNfNamingCode(vnf.getNfNamingCode()); + vf.setDataQuality(DataQuality.ok()); - String key = vnf.getVnfId(); - List vnfcLst = new ArrayList(); + String key = vnf.getVnfId(); // generic vnf-id (top level of the key) - for (Map.Entry> entry : vnfMap.entrySet()) { + // ---------------- Handle VNFC data + List vnfcLst = new ArrayList(); + for (Map.Entry> entry : vnfcMap.entrySet()) { if (key.equals(entry.getKey())) { List vnfcInstanceLst = entry.getValue(); @@ -278,55 +350,141 @@ public class RestUtil { VNFC vnfcModel = new VNFC(); vnfcModel.setInvariantUuid(vnfc.getModelInvariantId()); vnfcModel.setName(vnfc.getVnfcName()); - vnfcModel.setNfcNamingCode(vnfc.getNfcNamingCode()); vnfcModel.setUuid(vnfc.getModelVersionId()); vnfcLst.add(vnfcModel); } } } + vf.setVnfcs(vnfcLst); - vf.setVnfc(vnfcLst); - // Add the vfModule - List vfModuleLst = new ArrayList(); - if (vnf.getVfModules() != null) { - ConcurrentMap vnfModulemap = - buildMaxInstanceMap(vnf.getVfModules().getVfModule()); + // --------------- Handle the vfModule + //Map to calculate the Vf Module MaxInstance. + ConcurrentMap maxInstanceMap = + buildMaxInstanceMap(vnf.getVfModules().getVfModule()); - for (Map.Entry entry : vnfModulemap.entrySet()) { - String[] s = entry.getKey().split("\\" + DELIMITER); + List vfModuleLst = new ArrayList(); + for ( Map.Entry>> entry: vnf_vfmodule_vserver_Map.entrySet() ) { + // find the vnf-id + if (key.equals(entry.getKey())) { + + Map> vfmodule_vserver_map= entry.getValue(); + + for ( Map.Entry> vfmoduleEntry: vfmodule_vserver_map.entrySet() ){ + // The key is modelversionId$modelInvariantid + String[] s = vfmoduleEntry.getKey().split("\\" + DELIMITER); + String modelVersionId = s[0]; + String modelInvariantId = s[1]; + + VFModule vfModule = new VFModule(); + vfModule.setUuid(modelVersionId); + vfModule.setInvariantUuid(modelInvariantId); + vfModule.setMaxInstances(getMaxInstance(vfmoduleEntry.getKey(), maxInstanceMap)); + vfModule.setDataQuality(DataQuality.ok()); + + List vserverList = vfmoduleEntry.getValue(); + + // Handle VM + List vmList = new ArrayList(); + for (Vserver vserver: vserverList) { + + List attributeList = new ArrayList(); + + // Iterate through the ENUM Attribute list + for (Attribute.Name name: Attribute.Name.values()) { + if (name.toString().equals("lockedBoolean")) { + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.lockedBoolean); + att.setValue(String.valueOf(vserver.getInMaint())); + attributeList.add(att); + } + + if (name.toString().equals("hostName")) { + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.hostName); + att.setValue(getVserverAttribute(vserver, CATALOG_PSERVER)); + attributeList.add(att); + } + + if (name.toString().equals("imageId")) { + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.imageId); + att.setValue(getVserverAttribute(vserver, CATALOG_IMAGE)); + attributeList.add(att); + } + } + VM vm = new VM(); + vm.setUuid(vserver.getVserverId()); + vm.setName(vserver.getVserverName()); + vm.setAttributes(attributeList); + vmList.add(vm); + } + vfModule.setVms(vmList); + vfModuleLst.add(vfModule); + } - String modelVersionId = s[0]; - String modelInvariantId = s[1]; - VFModule vfModule = new VFModule(); - vfModule.setUuid(modelVersionId); - vfModule.setInvariantUuid(modelInvariantId); - vfModule.setMaxInstances(entry.getValue().intValue()); - vfModuleLst.add(vfModule); } } - vf.setVfModules(vfModuleLst); + vf.setVfModules(vfModuleLst); vfLst.add(vf); } // done the vnfInstance context.setService(service); - context.setVf(vfLst); + context.setVfs(vfLst); return context; } + /* + * Return the Vserver Attribute value by looking through the relationship. i.e. if "related-to" is "pserver", we will get + * the value of the attribute "hostname" from the last substring of the "related-link" + * { + * "related-to": "pserver", + * "related-link": "/aai/v11/cloud-infrastructure/pservers/pserver/rdm5r10c008.rdm5a.cci.att.com", + * "relationship-data": [ { + * "relationship-key": "pserver.hostname", + * "relationship-value": "rdm5r10c008.rdm5a.cci.att.com" + * }], + * "related-to-property": [{"property-key": "pserver.pserver-name2"}] + * }, + * + */ + private static String getVserverAttribute(Vserver vserver, String key) { + RelationshipList lst = vserver.getRelationshipList(); + if (lst != null) { + List relations = lst.getRelationship(); + for (Relationship re: relations) { + if (re.getRelatedTo().equals(key)) { + return extractAttValue(re.getRelatedLink()); + } + } + } + return null; + } + + + + /* + * Get the last substring from the related-link + * For example the value of the attribute "hostname" will be "rdm5r10c008.rdm5a.cci.att.com" + * "related-to": "pserver", + * "related-link": "/aai/v11/cloud-infrastructure/pservers/pserver/rdm5r10c008.rdm5a.cci.att.com", + */ + private static String extractAttValue(String relatedLink) { + return relatedLink.substring(relatedLink.lastIndexOf("/")+1); + } /* * Build the map with key (model_version_id and model_invariant_id), and with the max occurrences of * the value in the map * - * @param vfModuleList - * - * @return */ private static ConcurrentMap buildMaxInstanceMap(List vfModuleList) { @@ -348,6 +506,20 @@ public class RestUtil { } + /* + * Return the occurrence of the VfModule complex key: (model-version-id)+(model-invariant-id) + */ + private static int getMaxInstance(String key, ConcurrentMap maxInstanceMap) { + + for (Map.Entry entry : maxInstanceMap.entrySet()) { + + if (entry.getKey().equals(key)) { + return entry.getValue().intValue(); + } + + } + return 0; + } public static boolean isEmptyJson(String serviceInstancePayload) { @@ -355,7 +527,9 @@ public class RestUtil { return (serviceInstancePayload.equals(EMPTY_JSON_STRING)); } - + /* + * Debug purpose - Display the related-link list + */ private static String printOutAPIList(List relatedLinkLst) { StringBuilder builder = new StringBuilder(); @@ -383,7 +557,7 @@ public class RestUtil { JSONObject jsonPayload = new JSONObject(payload); JSONArray relationships = null; List relatedLinkList = new ArrayList(); - log.info("Fetching the vnfc related link"); + log.debug("Fetching the related link"); try { JSONObject relationshipList = jsonPayload.getJSONObject(RELATIONSHIP_LIST); @@ -417,9 +591,67 @@ public class RestUtil { return relatedLinkList; } + /* + * Return the Map with key: Vfmodule->model-version-id + Vfmoduel->model-invariant-id + * with value: list of the related-link based on the catalog + * The catalog can be "vserver" or "l3-network" based on common model requirement. + */ + private static Map> extractRelatedLinkFromVfmodule(String payload, String catalog) throws AuditException { + + Map> vServerRelatedLinkMap = new HashMap>(); + + JSONObject jsonPayload = new JSONObject(payload); + JSONArray vfmoduleArray = null; + JSONArray relationships = null; + + try { + log.debug("Fetching the Vf-module"); + JSONObject vfmodules = jsonPayload.getJSONObject(VF_MODULES); + if (vfmodules != null) { + vfmoduleArray = vfmodules.getJSONArray(VF_MODULE); + } + + if (vfmoduleArray != null && vfmoduleArray.length() > 0) { + for (int i = 0; i < vfmoduleArray.length(); i++) { + List relatedLinkList = new ArrayList(); + JSONObject obj = vfmoduleArray.optJSONObject(i); + String key = (String)obj.get("model-version-id") + DELIMITER + (String)obj.get("model-invariant-id"); + + log.debug("Fetching the relationship"); + JSONObject relationshipList = obj.getJSONObject(RELATIONSHIP_LIST); + if (relationshipList != null) { + relationships = relationshipList.getJSONArray(RELATIONSHIP); + } + if (relationships != null && relationships.length() > 0) { + for (int j = 0; j < relationships.length(); j++) { + Object relatedToObj = null; + Object relatedLinkObj = null; + + JSONObject obj2 = relationships.optJSONObject(j); + relatedToObj = obj2.get(JSON_ATT_RELATED_TO); + + if (relatedToObj.toString().equals(catalog)) { + relatedLinkObj = obj2.get(JSON_ATT_RELATED_LINK); + if (relatedLinkObj != null) { + relatedLinkList.add(relatedLinkObj.toString()); + } + } + } //relationship + } + + vServerRelatedLinkMap.put(key, relatedLinkList); + } //vf-module + } + + } catch (Exception e) { + log.error(e.getMessage()); + throw new AuditException(AuditError.JSON_READER_PARSE_ERROR + " " + e.getMessage()); + } + + return vServerRelatedLinkMap; + } - @SuppressWarnings("unchecked") private static Map> buildHeaders(String aaiBasicAuthorization, String transactionId) { MultivaluedMap headers = new MultivaluedMapImpl(); headers.put(TRANSACTION_ID, Collections.singletonList(transactionId)); @@ -446,11 +678,6 @@ public class RestUtil { } - private static String generateServiceInstanceURL(String siPath, String customerId, String serviceType, - String serviceInstanceId) { - return MessageFormat.format(siPath, customerId, serviceType, serviceInstanceId); - } - public static String obtainResouceLinkBasedOnServiceInstanceFromAAI(RestClient aaiClient, String baseURL, String aaiPathToSearchNodeQuery, String serviceInstanceId, String transactionId, String aaiBasicAuthorization) throws AuditException { @@ -467,7 +694,7 @@ public class RestUtil { return extractResourceLinkBasedOnResourceType(customerInfoString, CATALOG_SERVICE_INSTANCE); } - private static String generateGetCustomerInfoUrl (String baseURL, String aaiPathToSearchNodeQuery ,String serviceInstanceId) { + private static String generateGetCustomerInfoUrl (String baseURL, String aaiPathToSearchNodeQuery,String serviceInstanceId) { return baseURL + aaiPathToSearchNodeQuery + serviceInstanceId; } -- cgit 1.2.3-korg