From 85dda672f8d9a3bed20ca36852fa6e94c378f5b4 Mon Sep 17 00:00:00 2001 From: Norm Traxler Date: Fri, 1 Feb 2019 16:56:25 +0000 Subject: Ctx Builder l3-network support Issue-ID: SDNC-475 Network Discovery Ctx Builder to support l3-network attribute mapping to common model. Fix jenkins JUnit failures Change-Id: I64ded411a74ffb037df17a047c16e210d41c4992 Signed-off-by: Norm Traxler --- .../service/SpringServiceImpl.java | 191 +++++++-------------- .../service/rs/RestServiceImpl.java | 30 +++- .../networkdiscovery/util/TransformationUtil.java | 50 ++++++ 3 files changed, 144 insertions(+), 127 deletions(-) create mode 100644 src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/util/TransformationUtil.java (limited to 'src/main') diff --git a/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/SpringServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/SpringServiceImpl.java index 2df082c..774980b 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/SpringServiceImpl.java +++ b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/SpringServiceImpl.java @@ -24,8 +24,11 @@ import com.google.gson.Gson; import java.net.InetAddress; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; @@ -38,7 +41,6 @@ import javax.ws.rs.core.Response.Status; import javax.ws.rs.core.Response.Status.Family; import org.onap.aai.restclient.client.Headers; -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.Network; @@ -50,6 +52,7 @@ import org.onap.pomba.contextbuilder.networkdiscovery.model.NdResource; import org.onap.pomba.contextbuilder.networkdiscovery.model.NdResources; import org.onap.pomba.contextbuilder.networkdiscovery.service.rs.RestService; import org.onap.pomba.contextbuilder.networkdiscovery.util.RestUtil; +import org.onap.pomba.contextbuilder.networkdiscovery.util.TransformationUtil; import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.NetworkDiscoveryNotification; import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Resource; import org.slf4j.Logger; @@ -59,7 +62,10 @@ import org.springframework.beans.factory.annotation.Autowired; @org.springframework.stereotype.Service public class SpringServiceImpl implements SpringService { + private static final String ND_TYPE_VSERVER = "vserver"; + private static final String ND_TYPE_L3_NETWORK = "l3-network"; private static Logger log = LoggerFactory.getLogger(RestService.class); + public static final String APP_NAME = "NetworkDiscoveryContextBuilder"; public static final String MDC_REQUEST_ID = "RequestId"; @@ -193,134 +199,59 @@ public class SpringServiceImpl implements SpringService { return reply; } - private void updateNetworkDiscoveryCtx(ModelContext networkDiscoveryCtx, Resource resource) { - // Future: try to replace this with a Jolt transformation. - for (VNF vnf : networkDiscoveryCtx.getVnfs()) { - for (VFModule vfModule : vnf.getVfModules()) { - for (VM vm : vfModule.getVms()) { - if (vm.getUuid().equals(resource.getId()) && "vserver".equals(resource.getType())) { - vm.setDataQuality(resource.getDataQuality()); - if (null != resource.getAttributeList()) { - for (org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute ndattribute : resource - .getAttributeList()) { - try { - String ndattributeName = ndattribute.getName(); - // Some Network Discovery attribute name do not exactly - // match the pomba-audit-common model Attribute Enums, - // so we have to do some custom mapping here: - switch (ndattributeName) { - case "id": - vm.setUuid(ndattribute.getValue()); - break; - case "name": - vm.setName(ndattribute.getValue()); - break; - case "inMaintenance": - Attribute attribute = new Attribute(); - attribute.setName(Attribute.Name.lockedBoolean); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - vm.addAttribute(attribute); - break; - case "hostname": - attribute = new Attribute(); - attribute.setName(Attribute.Name.hostName); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - vm.addAttribute(attribute); - break; - default: - attribute = new Attribute(); - attribute.setName(Attribute.Name.valueOf(ndattributeName)); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - vm.addAttribute(attribute); - } - } catch (IllegalArgumentException ex) { - // The attribute Name passed back from Network Discovery is not in our enum - log.info("Attribute Name: {} for Resource: {} Id: {} is invalid", - ndattribute.getName(), resource.getName(), resource.getId()); - } - } - } - } - } - for (Network network : vfModule.getNetworks()) { - if (network.getUuid().equals(resource.getId()) && "l3-network".equals(resource.getType())) { - network.setDataQuality(resource.getDataQuality()); - if (null != resource.getAttributeList()) { - for (org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute ndattribute : resource - .getAttributeList()) { - try { - String ndattributeName = ndattribute.getName(); - // Some Network Discovery attribute name do not exactly - // match the pomba-audit-common model Attribute Enums, - // so we have to do some custom mapping here: - switch (ndattributeName) { - case "id": - network.setUuid(ndattribute.getValue()); - break; - case "name": - network.setName(ndattribute.getValue()); - break; - case "AdminState": - Attribute attribute = new Attribute(); - attribute.setName(Attribute.Name.adminStatus); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - network.addAttribute(attribute); - break; - case "sharedNetwork": - attribute = new Attribute(); - attribute.setName(Attribute.Name.sharedNetworkBoolean); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - network.addAttribute(attribute); - break; - default: - attribute = new Attribute(); - attribute.setName(Attribute.Name.valueOf(ndattributeName)); - attribute.setValue(ndattribute.getValue()); - attribute.setDataQuality(ndattribute.getDataQuality()); - network.addAttribute(attribute); - } - } catch (IllegalArgumentException ex) { - // The attribute Name passed back from Network Discovery is not in our enum - log.info("Attribute Name: {} for Resource: {} Id: {} is invalid", - ndattribute.getName(), resource.getName(), resource.getId()); - } - } - } - } - } + private void updateNetworkDiscoveryCtx(ModelContext networkDiscoveryCtx, Map resourceMap) { - } + for (Network network : networkDiscoveryCtx.getNetworkList()) { + updateNetworkInstance(resourceMap, network); } - } - private void updateNetworkDiscoveryCtxDataQuality(ModelContext networkDiscoveryCtx, String resourceId, - DataQuality dataQuality) { for (VNF vnf : networkDiscoveryCtx.getVnfs()) { + for (Network network : vnf.getNetworks()) { + updateNetworkInstance(resourceMap, network); + } + for (VFModule vfModule : vnf.getVfModules()) { for (VM vm : vfModule.getVms()) { - if (vm.getUuid().equals(resourceId)) { - vm.setDataQuality(dataQuality); - } + updateVmInstance(resourceMap, vm); } + for (Network network : vfModule.getNetworks()) { - if (network.getUuid().equals(resourceId)) { - network.setDataQuality(dataQuality); - } + updateNetworkInstance(resourceMap, network); } - } } } + private void updateVmInstance(Map resourceMap, VM vm) { + String resources = resourceMap.get(vm.getUuid()); + String resultJson = TransformationUtil.transform(resources, ND_TYPE_VSERVER); + + // copy the result into the VM class: + Gson gson = new Gson(); + VM ndVm = gson.fromJson(resultJson, VM.class); + vm.setName(ndVm.getName()); + vm.setDataQuality(ndVm.getDataQuality()); + vm.setAttributes(ndVm.getAttributes()); + } + + private void updateNetworkInstance(Map resourceMap, Network network) { + String resources = resourceMap.get(network.getUuid()); + String resultJson = TransformationUtil.transform(resources, ND_TYPE_L3_NETWORK); + + // copy the results into the Network class: + Gson gson = new Gson(); + Network ndNetwork = gson.fromJson(resultJson, Network.class); + network.setName(ndNetwork.getName()); + network.setDataQuality(ndNetwork.getDataQuality()); + network.setAttributes(ndNetwork.getAttributes()); + } + /* Return list of requestIds sent to network-discovery microService. */ private void sendNetworkDiscoveryRequest(ModelContext networkDiscoveryCtx, NdResources ndResources, String parentRequestId, String partnerName) throws DiscoveryException { - + + Map resourceMap = new HashMap<>(); + for (NdResource ndResource : ndResources.getNdResources()) { try { // The old_requestId is inherited from ServiceDecomposition. @@ -329,23 +260,33 @@ public class SpringServiceImpl implements SpringService { String requestId = parentRequestId + NETWORK_DISCOVERY_RSP_REQUESTID_SPLITTER + uniqueSeq.incrementAndGet(); - NetworkDiscoveryNotification nt = sendNetworkDiscoveryRequestToSpecificServer(partnerName, + String resultJson = sendNetworkDiscoveryRequestToSpecificServer(partnerName, parentRequestId, requestId, ndResource.getResourceId(), ndResource.getResourceType()); - List resourceList = nt.getResources(); - for (Resource resource1 : resourceList) { - updateNetworkDiscoveryCtx(networkDiscoveryCtx, resource1); - } + resourceMap.put(ndResource.getResourceId(), resultJson); } catch (Exception e) { - log.error("Error from Network Disovery Request - resourceId: {}, message: {}", + log.error("Error from Network Discovery Request - resourceId: {}, message: {}", ndResource.getResourceId(), e.getMessage()); - DataQuality dataQuality = DataQuality.error("Error from Network Disovery Request: " + e.getMessage()); - updateNetworkDiscoveryCtxDataQuality(networkDiscoveryCtx, ndResource.getResourceId(), dataQuality); + + // Build a fake Network Discovery error result, so it will be returned to the client: + Resource errorResource = new Resource(); + errorResource.setId(ndResource.getResourceId()); + DataQuality dataQuality = DataQuality.error(e.getMessage()); + errorResource.setDataQuality(dataQuality); + List resourceList = new ArrayList<>(); + resourceList.add(errorResource); + NetworkDiscoveryNotification ndErrorResult = new NetworkDiscoveryNotification(); + ndErrorResult.setResources(resourceList); + ndErrorResult.setCode(404); + Gson gson = new Gson(); + String ndErrorResultToJson = gson.toJson(ndErrorResult); + resourceMap.put(ndResource.getResourceId(), ndErrorResultToJson); } } + updateNetworkDiscoveryCtx(networkDiscoveryCtx, resourceMap); } - private NetworkDiscoveryNotification sendNetworkDiscoveryRequestToSpecificServer(String partnerName, + private String sendNetworkDiscoveryRequestToSpecificServer(String partnerName, String parentRequestId, String requestId, String resourceId, String resourceType) throws DiscoveryException { @@ -378,9 +319,9 @@ public class SpringServiceImpl implements SpringService { Response.Status.fromStatusCode(response.getStatus())); } - NetworkDiscoveryNotification ndResponse = response.readEntity(NetworkDiscoveryNotification.class); - log.info("Message sent. Response Payload: {}", ndResponse); - return ndResponse; + String ndResult = response.readEntity(String.class); + log.info("Message sent. Response ndResult: {}", ndResult); + return ndResult; } diff --git a/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/rs/RestServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/rs/RestServiceImpl.java index 67899ac..3a1b974 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/rs/RestServiceImpl.java +++ b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/service/rs/RestServiceImpl.java @@ -18,6 +18,8 @@ package org.onap.pomba.contextbuilder.networkdiscovery.service.rs; +import com.google.gson.ExclusionStrategy; +import com.google.gson.FieldAttributes; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -28,6 +30,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.Status; import org.onap.pomba.common.datatypes.ModelContext; +import org.onap.pomba.common.datatypes.VFModule; import org.onap.pomba.contextbuilder.networkdiscovery.exception.DiscoveryException; import org.onap.pomba.contextbuilder.networkdiscovery.exception.ErrorMessage; import org.onap.pomba.contextbuilder.networkdiscovery.service.SpringService; @@ -46,6 +49,27 @@ public class RestServiceImpl implements RestService { @Autowired private SpringService service; + /** + * Certain attributes in the common model do not apply (are not available) from network discovery. + * This exclusion strategy will make sure that any defaulted attributes that are not available/not valid are + * excluded from the json response. + * + * For now, there a two known attributes that need to be excluded from the VFModule: + * - minInstances (because it's an integer that defaults to zero) + * - maxInstances (because it's an integer that defaults to zero) + */ + public class ContextBuilderExclusionStrategy implements ExclusionStrategy { + + public boolean shouldSkipClass(Class arg0) { + return false; + } + + public boolean shouldSkipField(FieldAttributes f) { + return (f.getDeclaringClass() == VFModule.class && f.getName().equals("minInstances")) + || (f.getDeclaringClass() == VFModule.class && f.getName().equals("maxInstances")); + } + } + @Override public Response getContext(HttpServletRequest req, String authorization, String partnerName, String requestId, String fromAppId, String transactionId, String serviceInstanceId, String modelVersionId, @@ -79,7 +103,9 @@ public class RestServiceImpl implements RestService { // Return empty JSON return Response.ok().entity(EMPTY_JSON_OBJECT).build(); } else { - Gson gson = new GsonBuilder().create(); + GsonBuilder gsonBuilder = new GsonBuilder(); + gsonBuilder.setExclusionStrategies(new ContextBuilderExclusionStrategy()); + Gson gson = gsonBuilder.create(); return Response.ok().entity(gson.toJson(sdContext)).build(); } } catch (DiscoveryException x) { @@ -89,7 +115,7 @@ public class RestServiceImpl implements RestService { } catch (Exception x) { log.error(ErrorMessage.CONTEXT_BUILDER_FAILED, x); return Response.status(Status.INTERNAL_SERVER_ERROR).entity(x.getMessage()).build(); - + } finally { MDC.clear(); } diff --git a/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/util/TransformationUtil.java b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/util/TransformationUtil.java new file mode 100644 index 0000000..7e7af3e --- /dev/null +++ b/src/main/java/org/onap/pomba/contextbuilder/networkdiscovery/util/TransformationUtil.java @@ -0,0 +1,50 @@ +/* + * Copyright 2014 Bazaarvoice, Inc. + * + * 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. + */ +package org.onap.pomba.contextbuilder.networkdiscovery.util; + +import com.bazaarvoice.jolt.Chainr; +import com.bazaarvoice.jolt.JsonUtils; + +import java.io.File; +import java.util.List; + +public class TransformationUtil { + + private static final String CONFIG_JOLT = "config/jolt"; + + private TransformationUtil() { + throw new IllegalStateException("Utility class"); + } + + /** + * Transforms the sourceJson using the jolt specification for the given resourceType. + * + * @param sourceJson + * @param resourceType + * @return + */ + public static String transform(String sourceJson, String resourceType) { + + Object sourceObject = JsonUtils.jsonToObject(sourceJson); + + List chainrSpecJSON = JsonUtils.filepathToList(CONFIG_JOLT + File.separator + resourceType + "Spec.json"); + Chainr chainr = Chainr.fromSpec(chainrSpecJSON); + Object output = chainr.transform(sourceObject); + + return JsonUtils.toJsonString(output); + } + +} \ No newline at end of file -- cgit 1.2.3-korg