From 0d37e2c3db490fac0b7b7e53612dbf9450bb2841 Mon Sep 17 00:00:00 2001 From: Ittay Stern Date: Wed, 31 Jul 2019 10:26:39 +0300 Subject: Handle A&AI Service-Tree and add tests Issue-ID: VID-378 Change-Id: Id1b86b77732768f9b497e2fcd29ee1665381ac57 Signed-off-by: Ittay Stern --- .../src/main/java/org/onap/vid/aai/AaiClient.java | 43 ++++--- .../java/org/onap/vid/controller/WebConfig.java | 12 +- .../java/org/onap/vid/roles/RoleValidator.java | 6 +- .../java/org/onap/vid/services/AaiService.java | 13 +- .../java/org/onap/vid/services/AaiServiceImpl.java | 131 ++++++++++++++++----- 5 files changed, 137 insertions(+), 68 deletions(-) (limited to 'vid-app-common/src/main/java') diff --git a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java index 015ede893..a0296d9d9 100644 --- a/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java +++ b/vid-app-common/src/main/java/org/onap/vid/aai/AaiClient.java @@ -20,6 +20,7 @@ package org.onap.vid.aai; +import static com.fasterxml.jackson.module.kotlin.ExtensionsKt.jacksonObjectMapper; import static java.util.Collections.emptyList; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.toMap; @@ -27,7 +28,6 @@ import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; import static org.apache.commons.lang3.StringUtils.equalsIgnoreCase; import static org.apache.commons.lang3.StringUtils.isEmpty; -import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; @@ -46,13 +46,13 @@ import javax.ws.rs.core.Response; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpStatus; import org.apache.http.client.utils.URIBuilder; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.jetbrains.annotations.NotNull; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; import org.onap.vid.aai.exceptions.InvalidAAIResponseException; -import org.onap.vid.aai.model.*; import org.onap.vid.aai.model.AaiGetAicZone.AicZones; import org.onap.vid.aai.model.AaiGetInstanceGroupsByCloudRegion; import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.AaiGetNetworkCollectionDetails; @@ -69,6 +69,8 @@ import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse; import org.onap.vid.aai.model.CustomQuerySimpleResult; import org.onap.vid.aai.model.GetServiceModelsByDistributionStatusResponse; import org.onap.vid.aai.model.LogicalLinkResponse; +import org.onap.vid.aai.model.ModelVer; +import org.onap.vid.aai.model.ModelVersions; import org.onap.vid.aai.model.OwningEntityResponse; import org.onap.vid.aai.model.PortDetailsTranslator; import org.onap.vid.aai.model.ProjectResponse; @@ -89,14 +91,10 @@ import org.onap.vid.utils.Unchecked; import org.springframework.http.HttpMethod; import org.springframework.web.util.UriUtils; -/** - - * Created by Oren on 7/4/17. - */ public class AaiClient implements AaiClientInterface { - private static final String QUERY_FORMAT_RESOURCE = "query?format=resource"; + public static final String QUERY_FORMAT_RESOURCE = "query?format=resource"; private static final String SERVICE_SUBSCRIPTIONS_PATH = "/service-subscriptions/service-subscription/"; private static final String MODEL_INVARIANT_ID = "&model-invariant-id="; private static final String QUERY_FORMAT_SIMPLE = "query?format=simple"; @@ -112,15 +110,14 @@ public class AaiClient implements AaiClientInterface { private final CacheProvider cacheProvider; - ObjectMapper objectMapper = new ObjectMapper(); + ObjectMapper objectMapper = jacksonObjectMapper(); /** * The logger */ EELFLoggerDelegate logger = EELFLoggerDelegate.getLogger(AaiClient.class); - private static final String GET_SERVICE_MODELS_RESPONSE_BODY = "{\"start\" : \"service-design-and-creation/models/\", \"query\" : \"query/serviceModels-byDistributionStatus?distributionStatus=DISTRIBUTION_COMPLETE_OK\"}"; - + private static final String GET_SERVICE_MODELS_REQUEST_BODY = "{\"start\" : \"service-design-and-creation/models/\", \"query\" : \"query/serviceModels-byDistributionStatus?distributionStatus=DISTRIBUTION_COMPLETE_OK\"}"; @Inject public AaiClient(AAIRestInterface restController, PortDetailsTranslator portDetailsTranslator, CacheProvider cacheProvider) { @@ -158,7 +155,7 @@ public class AaiClient implements AaiClientInterface { private AaiResponse getServiceModelsByDistributionStatusNonCached(boolean propagateExceptions) { GetServiceModelsByDistributionStatusResponse response = typedAaiRest(QUERY_FORMAT_RESOURCE, GetServiceModelsByDistributionStatusResponse.class, - GET_SERVICE_MODELS_RESPONSE_BODY, HttpMethod.PUT, propagateExceptions); + GET_SERVICE_MODELS_REQUEST_BODY, HttpMethod.PUT, propagateExceptions); return new AaiResponse(response, "", HttpStatus.SC_OK); } @@ -426,16 +423,7 @@ public class AaiClient implements AaiClientInterface { sb.append(id); } - return doAaiGet("service-design-and-creation/models?depth=2"+ sb.toString(), false); - } - - @Override - public AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances) { - String depth = omitServiceInstances ? "1" : "2"; - AaiResponse subscriberDataResponse; - Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false); - subscriberDataResponse = processAaiResponse(resp, Services.class, null); - return subscriberDataResponse; + return doAaiGet("service-design-and-creation/models?depth=2" + sb.toString(), false); } @Override @@ -445,7 +433,7 @@ public class AaiClient implements AaiClientInterface { } // add the modelInvariantId to the payload - StringBuilder payload = new StringBuilder(GET_SERVICE_MODELS_RESPONSE_BODY); + StringBuilder payload = new StringBuilder(GET_SERVICE_MODELS_REQUEST_BODY); payload.insert(50, modelInvariantId); Response response = doAaiPut("service-design-and-creation/models/model/", payload.toString(),false); @@ -473,6 +461,15 @@ public class AaiClient implements AaiClientInterface { .orElseThrow(() -> new GenericUncheckedException("Could not find any version")); } + @Override + public AaiResponse getSubscriberData(String subscriberId, boolean omitServiceInstances) { + String depth = omitServiceInstances ? "1" : "2"; + AaiResponse subscriberDataResponse; + Response resp = doAaiGet(BUSINESS_CUSTOMERS_CUSTOMER + subscriberId + "?depth=" + depth, false); + subscriberDataResponse = processAaiResponse(resp, Services.class, null); + return subscriberDataResponse; + } + @Override public AaiResponse getServices() { Response resp = doAaiGet("service-design-and-creation/services", false); @@ -494,7 +491,7 @@ public class AaiClient implements AaiClientInterface { @Override public AaiResponse getTenants(String globalCustomerId, String serviceType) { - if ((globalCustomerId == null || globalCustomerId.isEmpty()) || ((serviceType == null) || (serviceType.isEmpty())) ){ + if ((globalCustomerId == null || globalCustomerId.isEmpty()) || ((serviceType == null) || (serviceType.isEmpty()))){ return buildAaiResponseForGetTenantsFailure(" Failed to retrieve LCP Region & Tenants from A&AI, Subscriber ID or Service Type is missing."); } try { diff --git a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java index 6f4ce4ddb..71c6bf345 100644 --- a/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java +++ b/vid-app-common/src/main/java/org/onap/vid/controller/WebConfig.java @@ -22,7 +22,6 @@ package org.onap.vid.controller; import static org.apache.commons.lang3.ObjectUtils.defaultIfNull; - import static org.apache.commons.lang3.StringUtils.isEmpty; import com.fasterxml.jackson.core.JsonProcessingException; @@ -30,8 +29,9 @@ import com.fasterxml.jackson.module.kotlin.KotlinModule; import io.joshworks.restclient.http.mapper.ObjectMapper; import java.io.File; import java.io.IOException; -import javax.servlet.ServletContext; +import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import javax.servlet.ServletContext; import org.onap.portalsdk.core.util.SystemProperties; import org.onap.vid.aai.AaiClient; import org.onap.vid.aai.AaiClientInterface; @@ -77,12 +77,6 @@ import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; - -import javax.servlet.ServletContext; -import java.io.File; -import java.io.IOException; -import java.util.concurrent.ExecutorService; - @EnableSwagger2 @Configuration public class WebConfig { @@ -106,7 +100,7 @@ public class WebConfig { @Bean public AaiService getAaiService(AaiClientInterface aaiClient, AaiOverTLSClientInterface aaiOverTLSClient, AaiResponseTranslator aaiResponseTranslator, AAITreeNodeBuilder aaiTreeNode, AAIServiceTree aaiServiceTree, ExecutorService executorService) { - return new AaiServiceImpl(aaiClient, aaiOverTLSClient, aaiResponseTranslator, aaiTreeNode, aaiServiceTree, executorService); + return new AaiServiceImpl(aaiClient, aaiOverTLSClient, aaiResponseTranslator, aaiServiceTree, executorService); } @Bean diff --git a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java index d37477610..830c0f50c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java +++ b/vid-app-common/src/main/java/org/onap/vid/roles/RoleValidator.java @@ -28,9 +28,11 @@ import org.onap.portalsdk.core.util.SystemProperties; public interface RoleValidator { static RoleValidator by(List roles) { - boolean disableRoles = - StringUtils.equals(SystemProperties.getProperty("role_management_activated"), "false"); + final boolean disableRoles = StringUtils.equals(SystemProperties.getProperty("role_management_activated"), "false"); + return by(roles, disableRoles); + } + static RoleValidator by(List roles, boolean disableRoles) { return disableRoles ? new AlwaysValidRoleValidator() : new RoleValidatorByRoles(roles); diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java index 76efbd0ea..6c63ae07c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiService.java @@ -22,6 +22,9 @@ package org.onap.vid.services; import io.joshworks.restclient.http.HttpResponse; +import java.util.Collection; +import java.util.List; +import javax.ws.rs.core.Response; import org.onap.vid.aai.AaiGetVnfResponse; import org.onap.vid.aai.AaiResponse; import org.onap.vid.aai.AaiResponseTranslator; @@ -33,13 +36,11 @@ import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse; import org.onap.vid.aai.model.PortDetailsTranslator; import org.onap.vid.asdc.beans.Service; import org.onap.vid.model.SubscriberList; +import org.onap.vid.model.aaiTree.Network; import org.onap.vid.model.aaiTree.RelatedVnf; +import org.onap.vid.model.aaiTree.VpnBinding; import org.onap.vid.roles.RoleValidator; -import javax.ws.rs.core.Response; -import java.util.Collection; -import java.util.List; - /** * Created by Oren on 7/4/17. */ @@ -95,4 +96,8 @@ public interface AaiService { GetTenantsResponse getHomingDataByVfModule(String vnfInstanceId, String vfModuleId); List searchGroupMembers(String globalCustomerId, String serviceType, String invariantId, String groupType, String groupRole); + + List getVpnListByVpnType(String vpnType); + + List getL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole); } diff --git a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java index 961f11096..fcdae441c 100644 --- a/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java +++ b/vid-app-common/src/main/java/org/onap/vid/services/AaiServiceImpl.java @@ -21,43 +21,79 @@ package org.onap.vid.services; +import static org.onap.vid.aai.AaiClient.QUERY_FORMAT_RESOURCE; +import static org.onap.vid.utils.KotlinUtilsKt.JACKSON_OBJECT_MAPPER; + import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; import io.joshworks.restclient.http.HttpResponse; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.concurrent.ExecutorService; +import java.util.stream.Collectors; +import javax.validation.constraints.NotNull; +import javax.ws.rs.core.Response; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpStatus; import org.onap.portalsdk.core.logging.logic.EELFLoggerDelegate; -import org.onap.vid.aai.*; -import org.onap.vid.aai.model.*; +import org.onap.vid.aai.AaiClientInterface; +import org.onap.vid.aai.AaiGetVnfResponse; +import org.onap.vid.aai.AaiOverTLSClientInterface; +import org.onap.vid.aai.AaiResponse; +import org.onap.vid.aai.AaiResponseTranslator; +import org.onap.vid.aai.ExceptionWithRequestInfo; +import org.onap.vid.aai.ServiceInstance; +import org.onap.vid.aai.ServiceInstancesSearchResults; +import org.onap.vid.aai.ServiceSubscription; +import org.onap.vid.aai.ServiceSubscriptions; +import org.onap.vid.aai.Services; +import org.onap.vid.aai.SubscriberFilteredResults; +import org.onap.vid.aai.model.AaiGetInstanceGroupsByCloudRegion; import org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.AaiGetRelatedInstanceGroupsByVnfId; import org.onap.vid.aai.model.AaiGetOperationalEnvironments.OperationalEnvironmentList; import org.onap.vid.aai.model.AaiGetPnfs.Pnf; import org.onap.vid.aai.model.AaiGetServicesRequestModel.GetServicesAAIRespone; -import org.onap.vid.aai.model.Properties; import org.onap.vid.aai.model.AaiGetTenatns.GetTenantsResponse; +import org.onap.vid.aai.model.AaiRelationResponse; +import org.onap.vid.aai.model.GetServiceModelsByDistributionStatusResponse; +import org.onap.vid.aai.model.InstanceGroupInfo; +import org.onap.vid.aai.model.LogicalLinkResponse; +import org.onap.vid.aai.model.Model; +import org.onap.vid.aai.model.ModelVer; +import org.onap.vid.aai.model.OwningEntity; +import org.onap.vid.aai.model.OwningEntityResponse; +import org.onap.vid.aai.model.PortDetailsTranslator; +import org.onap.vid.aai.model.Project; +import org.onap.vid.aai.model.ProjectResponse; +import org.onap.vid.aai.model.Properties; +import org.onap.vid.aai.model.RelatedToProperty; +import org.onap.vid.aai.model.Relationship; +import org.onap.vid.aai.model.RelationshipData; +import org.onap.vid.aai.model.RelationshipList; +import org.onap.vid.aai.model.Result; +import org.onap.vid.aai.model.ServiceRelationships; +import org.onap.vid.aai.model.VnfResult; import org.onap.vid.asdc.beans.Service; import org.onap.vid.exceptions.GenericUncheckedException; import org.onap.vid.model.ServiceInstanceSearchResult; import org.onap.vid.model.SubscriberList; import org.onap.vid.model.aaiTree.AAITreeNode; +import org.onap.vid.model.aaiTree.Network; import org.onap.vid.model.aaiTree.NodeType; import org.onap.vid.model.aaiTree.RelatedVnf; +import org.onap.vid.model.aaiTree.VpnBinding; +import org.onap.vid.model.aaiTree.VpnBindingKt; import org.onap.vid.roles.RoleValidator; import org.onap.vid.utils.Intersection; import org.onap.vid.utils.Tree; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpMethod; -import javax.ws.rs.core.Response; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.stream.Collectors; - -/** - * Created by Oren on 7/4/17. - */ public class AaiServiceImpl implements AaiService { private static final String SERVICE_INSTANCE_ID = "service-instance.service-instance-id"; private static final String SERVICE_TYPE = "service-subscription.service-type"; @@ -70,7 +106,6 @@ public class AaiServiceImpl implements AaiService { private AaiClientInterface aaiClient; private AaiOverTLSClientInterface aaiOverTLSClient; private AaiResponseTranslator aaiResponseTranslator; - private AAITreeNodeBuilder aaiTreeNode; private AAIServiceTree aaiServiceTree; private ExecutorService executorService; @@ -82,14 +117,12 @@ public class AaiServiceImpl implements AaiService { AaiClientInterface aaiClient, AaiOverTLSClientInterface aaiOverTLSClient, AaiResponseTranslator aaiResponseTranslator, - AAITreeNodeBuilder aaiTreeNode, AAIServiceTree aaiServiceTree, ExecutorService executorService) { this.aaiClient = aaiClient; this.aaiOverTLSClient = aaiOverTLSClient; this.aaiResponseTranslator = aaiResponseTranslator; - this.aaiTreeNode = aaiTreeNode; this.aaiServiceTree = aaiServiceTree; this.executorService = executorService; } @@ -365,18 +398,18 @@ public class AaiServiceImpl implements AaiService { return filterChangeManagementVNFCandidatesResponse(response); } - private AaiResponse filterChangeManagementVNFCandidatesResponse(AaiResponse response) { - + protected AaiResponse filterChangeManagementVNFCandidatesResponse(AaiResponse response) { if (response != null && response.getT() != null) { - response.getT().results = - response.getT().results.stream() - .filter(result -> ( - result.nodeType.equalsIgnoreCase("generic-vnf") || - result.nodeType.equalsIgnoreCase("service-instance"))) - .collect(Collectors.toList()); - - return response; + List filteredVnfs = response.getT().results.stream() + .filter(result -> ( + result.nodeType.equalsIgnoreCase("generic-vnf") || + result.nodeType.equalsIgnoreCase("service-instance"))) + .collect(Collectors.toList()); + + AaiGetVnfResponse aaiGetVnfResponse = new AaiGetVnfResponse(); + aaiGetVnfResponse.results = filteredVnfs; + return new AaiResponse<>(aaiGetVnfResponse, response.getErrorMessage(), response.getHttpCode()); } return new AaiResponse<>(); @@ -521,7 +554,6 @@ public class AaiServiceImpl implements AaiService { } } - private List filterByInstanceGroupRoleAndType(List aaiTree, String groupRole, String groupType) { return aaiTree.stream() @@ -554,6 +586,7 @@ public class AaiServiceImpl implements AaiService { return vnf; } + private List convertGetInstanceGroupsResponseToSimpleResponse(AaiGetRelatedInstanceGroupsByVnfId response) { List instanceGroupInfoList = new ArrayList<>(); for(org.onap.vid.aai.model.AaiGetNetworkCollectionDetails.Relationship relationship: response.getRelationshipList().getRelationship()){ @@ -628,14 +661,52 @@ public class AaiServiceImpl implements AaiService { } public String getAAIServiceTree(String globalCustomerId, String serviceType, String serviceInstanceId) { - ObjectMapper om = new ObjectMapper(); String result; try { org.onap.vid.model.aaiTree.ServiceInstance tree = aaiServiceTree.getServiceInstanceTopology(globalCustomerId, serviceType, serviceInstanceId); - result = om.writeValueAsString(tree); + result = JACKSON_OBJECT_MAPPER.writeValueAsString(tree); } catch (Exception e) { throw new GenericUncheckedException(e); } return result; } + + @Override + public List getVpnListByVpnType(String vpnType) { + String path = "network/vpn-bindings?vpn-type=" + vpnType; + + try { + List aaiTree = aaiServiceTree.buildAAITreeForUniqueResource(path, NodeType.VPN_BINDING); + return aaiTree.stream().map(VpnBindingKt::from).collect(Collectors.toList()); + } catch (ExceptionWithRequestInfo exception) { + if (Objects.equals(404, exception.getHttpCode())) { + return Collections.emptyList(); + } + throw exception; + } + + } + + @Override + public List getL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole) { + String payload = buildPayloadForL3NetworksByCloudRegion(cloudRegionId, tenantId, networkRole); + + try { + List aaiTree = aaiServiceTree.buildAAITreeForUniqueResourceFromCustomQuery(QUERY_FORMAT_RESOURCE, payload, HttpMethod.PUT, NodeType.NETWORK); + return aaiTree.stream().map(Network::from).collect(Collectors.toList()); + } catch (ExceptionWithRequestInfo exception) { + if (Objects.equals(404, exception.getHttpCode())) { + return Collections.emptyList(); + } + throw exception; + } + } + + @NotNull + protected String buildPayloadForL3NetworksByCloudRegion(String cloudRegionId, String tenantId, String networkRole) { + String networkRolePart = StringUtils.isEmpty(networkRole) ? "" : "&networkRole=" + networkRole; + String cloudOwner = aaiClient.getCloudOwnerByCloudRegionId(cloudRegionId); + return "{\"start\":\"/cloud-infrastructure/cloud-regions/cloud-region/" + cloudOwner + "/" + cloudRegionId + "\"," + + "\"query\":\"query/l3-networks-by-cloud-region?tenantId=" + tenantId + networkRolePart + "\"}"; + } } -- cgit 1.2.3-korg