Merge "Delegate class for service level preparation BB"
authorByung-Woo Jun <byung-woo.jun@est.tech>
Wed, 5 Aug 2020 13:21:40 +0000 (13:21 +0000)
committerGerrit Code Review <gerrit@onap.org>
Wed, 5 Aug 2020 13:21:40 +0000 (13:21 +0000)
28 files changed:
adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java
adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java
adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java
bpmn/MSOCommonBPMN/src/main/java/org/onap/so/client/restproperties/CDSPropertiesImpl.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/utils/SdncInputParametersProvider.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/utils/UserParamInputParametersProvider.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/adapter/vnfm/tasks/utils/VnfParameter.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/WorkflowAction.java
bpmn/so-bpmn-tasks/src/main/java/org/onap/so/bpmn/infrastructure/workflow/tasks/listeners/HomingListener.java
bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/listeners/HomingListenerTest.java [new file with mode: 0644]
common/pom.xml
common/src/main/java/org/onap/so/client/KeyStoreLoader.java [new file with mode: 0644]
common/src/main/java/org/onap/so/client/RestClientSSL.java
common/src/main/java/org/onap/so/client/cds/CDSProcessingClient.java
common/src/main/java/org/onap/so/client/cds/CDSProperties.java
common/src/test/java/org/onap/so/client/cds/CDSProcessingClientTest.java
common/src/test/java/org/onap/so/client/cds/TestCDSPropertiesImpl.java
docs/developer_info/Working_with_so_monitoring.rst [new file with mode: 0644]
docs/developer_info/developer_information.rst
docs/images/configmap.png [new file with mode: 0644]
docs/images/nodemap.png [new file with mode: 0644]
docs/images/nodeport.png [new file with mode: 0644]
docs/images/ui.png [new file with mode: 0644]
pom.xml
so-sdn-clients/pom.xml

index df4229c..12751f8 100644 (file)
@@ -35,6 +35,7 @@ import org.openstack4j.model.compute.Flavor;
 import org.openstack4j.model.compute.Image;
 import org.openstack4j.model.compute.Server;
 import org.openstack4j.model.heat.Resource;
+import org.openstack4j.model.network.Network;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -72,6 +73,10 @@ public class CreateAAIInventory {
             List<Resource> stackResources =
                     heatBridgeClient.queryNestedHeatStackResources(cloudInformation.getTemplateInstanceId());
 
+            List<Network> osNetworks = heatBridgeClient.getAllOpenstackProviderNetworks(stackResources);
+            heatBridgeClient.buildAddNetworksToAaiAction(cloudInformation.getVnfId(), cloudInformation.getVfModuleId(),
+                    osNetworks);
+
             List<Server> osServers = heatBridgeClient.getAllOpenstackServers(stackResources);
 
             heatBridgeClient.createPserversAndPinterfacesIfNotPresentInAai(stackResources);
index 9c09886..a4e6ccc 100644 (file)
@@ -38,6 +38,7 @@ import org.openstack4j.model.compute.Flavor;
 import org.openstack4j.model.compute.Image;
 import org.openstack4j.model.compute.Server;
 import org.openstack4j.model.heat.Resource;
+import org.openstack4j.model.network.Network;
 
 /**
  * Defines the contract to extract Heat Stack Resources from Openstack and inventory it to AAI. This API is used only to
@@ -87,6 +88,14 @@ public interface HeatBridgeApi {
      */
     List<Server> getAllOpenstackServers(List<Resource> stackResources);
 
+    /**
+     * Query the Openstack provider network objects from the list of stack resources
+     *
+     * @param stackResources A list of stack based resources
+     * @return A list of Openstack Network objects
+     */
+    List<Network> getAllOpenstackProviderNetworks(final List<Resource> stackResources);
+
     /**
      * Extract Openstack Image objects from a a list of Server objects
      *
@@ -103,6 +112,15 @@ public interface HeatBridgeApi {
      */
     List<Flavor> extractOpenstackFlavorsFromServers(List<Server> servers);
 
+    /**
+     * Query and build AAI actions for Openstack Compute resources to AAI's l3-network objects with its subnets
+     *
+     * @param genericVnfId AAI generic-vnf-id
+     * @param vfModuleId AAI vf-module-id
+     * @param networks Openstack Network list
+     */
+    void buildAddNetworksToAaiAction(final String genericVnfId, final String vfModuleId, List<Network> networks);
+
     /**
      * Query and build AAI actions for Openstack Image resources to AAI's image objects
      *
index e537b24..9295800 100644 (file)
@@ -49,11 +49,15 @@ import org.apache.commons.validator.routines.InetAddressValidator;
 import org.onap.aai.domain.yang.Flavor;
 import org.onap.aai.domain.yang.Image;
 import org.onap.aai.domain.yang.L3InterfaceIpv4AddressList;
+import org.onap.aai.domain.yang.L3Network;
 import org.onap.aai.domain.yang.LInterface;
 import org.onap.aai.domain.yang.PInterface;
 import org.onap.aai.domain.yang.Pserver;
+import org.onap.aai.domain.yang.Relationship;
+import org.onap.aai.domain.yang.RelationshipList;
 import org.onap.aai.domain.yang.SriovPf;
 import org.onap.aai.domain.yang.SriovPfs;
+import org.onap.aai.domain.yang.Subnets;
 import org.onap.aai.domain.yang.SriovVf;
 import org.onap.aai.domain.yang.SriovVfs;
 import org.onap.aai.domain.yang.VfModule;
@@ -197,6 +201,16 @@ public class HeatBridgeImpl implements HeatBridgeApi {
         return serverIds.stream().map(serverId -> osClient.getServerById(serverId)).collect(Collectors.toList());
     }
 
+    @Override
+    public List<Network> getAllOpenstackProviderNetworks(final List<Resource> stackResources) {
+        Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT);
+        // Filter Openstack Compute resources
+        List<String> providerNetworkIds =
+                extractStackResourceIdsByResourceType(stackResources, HeatBridgeConstants.OS_NEUTRON_PROVIDERNET);
+        return providerNetworkIds.stream().map(providerNetworkId -> osClient.getNetworkById(providerNetworkId))
+                .collect(Collectors.toList());
+    }
+
     @Override
     public List<org.openstack4j.model.compute.Image> extractOpenstackImagesFromServers(final List<Server> servers) {
         Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT);
@@ -211,6 +225,27 @@ public class HeatBridgeImpl implements HeatBridgeApi {
                 .filter(distinctByProperty(org.openstack4j.model.compute.Flavor::getId)).collect(Collectors.toList());
     }
 
+    public void buildAddNetworksToAaiAction(final String genericVnfId, final String vfModuleId,
+            List<Network> networks) {
+        networks.forEach(network -> {
+            L3Network l3Network = aaiHelper.buildNetwork(network);
+            if (l3Network != null) {
+                l3Network.setSubnets(buildSunets(network));
+
+                RelationshipList relationshipList = new RelationshipList();
+                List<Relationship> relationships = relationshipList.getRelationship();
+
+                relationships.add(aaiHelper.getRelationshipToVfModule(genericVnfId, vfModuleId));
+                relationships.add(aaiHelper.getRelationshipToTenant(cloudOwner, cloudRegionId, tenantId));
+
+                l3Network.setRelationshipList(relationshipList);
+                transaction.createIfNotExists(
+                        AAIUriFactory.createResourceUri(AAIObjectType.L3_NETWORK, l3Network.getNetworkId()),
+                        Optional.of(l3Network));
+            }
+        });
+    }
+
     @Override
     public void buildAddImagesToAaiAction(final List<org.openstack4j.model.compute.Image> images)
             throws HeatBridgeException {
@@ -338,6 +373,20 @@ public class HeatBridgeImpl implements HeatBridgeApi {
         return pserverMap;
     }
 
+    private Subnets buildSunets(Network network) {
+        Subnets aaiSubnets = new Subnets();
+        List<String> subnetIds = network.getSubnets();
+
+        subnetIds.forEach(subnetId -> {
+            Subnet subnet = osClient.getSubnetById(subnetId);
+            org.onap.aai.domain.yang.Subnet aaiSubnet = aaiHelper.buildSubnet(subnet);
+            if (aaiSubnet != null) {
+                aaiSubnets.getSubnet().add(aaiSubnet);
+            }
+        });
+        return aaiSubnets;
+    }
+
     private void createPServerIfNotExists(Map<String, Pserver> serverHostnames) {
         for (Pserver pserver : serverHostnames.values()) {
             AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.PSERVER, pserver.getHostname());
index fdf7ce3..71c6a96 100644 (file)
@@ -40,6 +40,7 @@ public class HeatBridgeConstants {
     public static final Integer OS_DEFAULT_HEAT_NESTING = 5;
     public static final String OS_SERVER_RESOURCE_TYPE = "OS::Nova::Server";
     public static final String OS_PORT_RESOURCE_TYPE = "OS::Neutron::Port";
+    public static final String OS_NEUTRON_PROVIDERNET = "OS::Neutron::ProviderNet";
     public static final String OS_SRIOV_PORT_TYPE = "direct";
     public static final String OS_PCI_SLOT_KEY = "pci_slot";
     public static final String OS_PHYSICAL_NETWORK_KEY = "physical_network";
@@ -64,6 +65,8 @@ public class HeatBridgeConstants {
     public static final String AAI_VF_MODULE_ID = "vf-module.vf-module-id";
     public static final String AAI_IMAGE = "image";
     public static final String AAI_IMAGE_ID = "image.image-id";
+    public static final String AAI_TENANT = "tenant";
+    public static final String AAI_TENANT_ID = "tenant.tenant-id";
     public static final String AAI_CLOUD_OWNER = "cloud-region.cloud-owner";
     public static final String AAI_CLOUD_REGION_ID = "cloud-region.cloud-region-id";
     public static final String AAI_FLAVOR = "flavor";
index c4d9cbe..7d4e92d 100644 (file)
@@ -42,6 +42,7 @@ import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.onap.aai.domain.yang.Flavor;
 import org.onap.aai.domain.yang.Image;
+import org.onap.aai.domain.yang.L3Network;
 import org.onap.aai.domain.yang.PInterface;
 import org.onap.aai.domain.yang.Pserver;
 import org.onap.aai.domain.yang.Relationship;
@@ -54,7 +55,9 @@ import org.onap.aaiclient.client.aai.entities.uri.AAIResourceUri;
 import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
 import org.openstack4j.model.compute.Server;
+import org.openstack4j.model.network.Network;
 import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.Subnet;
 import com.google.common.base.Preconditions;
 
 /**
@@ -131,6 +134,49 @@ public class AaiHelper {
         return relationshipList;
     }
 
+    public Relationship getRelationshipToVfModule(String vnfId, String vfModuleId) {
+        return buildRelationship(AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId));
+    }
+
+    public Relationship getRelationshipToTenant(String cloudOwner, String cloudRegionId, String tenantId) {
+        return buildRelationship(
+                AAIUriFactory.createResourceUri(AAIObjectType.TENANT, cloudOwner, cloudRegionId, tenantId));
+    }
+
+    public org.onap.aai.domain.yang.Subnet buildSubnet(Subnet subnet) {
+        org.onap.aai.domain.yang.Subnet aaiSubnet = new org.onap.aai.domain.yang.Subnet();
+        aaiSubnet.setSubnetId(subnet.getId());
+        aaiSubnet.setDhcpEnabled(subnet.isDHCPEnabled());
+
+        aaiSubnet.setSubnetName(subnet.getName());
+        aaiSubnet.setGatewayAddress(subnet.getGateway());
+        aaiSubnet.setCidrMask(subnet.getCidr());
+        aaiSubnet.setIpVersion(subnet.getIpVersion().name());
+        return aaiSubnet;
+    }
+
+    public L3Network buildNetwork(Network network) {
+        if (network.getId() == null) {
+            return null;
+        }
+        L3Network l3Network = new L3Network();
+        l3Network.setNetworkId(network.getId());
+        l3Network.setIsBoundToVpn(true);
+        l3Network.setIsProviderNetwork(true);
+
+        // optional fields
+        l3Network.setIsSharedNetwork(network.isShared());
+        l3Network.setIsExternalNetwork(network.isRouterExternal());
+        l3Network.setOperationalStatus(String.valueOf(network.isAdminStateUp()));
+        if (network.getName() != null) {
+            l3Network.setNetworkName(network.getName());
+        }
+        if (network.getProviderPhyNet() != null) {
+            l3Network.setPhysicalNetworkName(network.getProviderPhyNet());
+        }
+        return l3Network;
+    }
+
     /**
      * Transform Openstack Server object to AAI Vserver object
      *
index 643dd4c..8c21e3f 100644 (file)
@@ -85,9 +85,11 @@ import org.openstack4j.model.compute.Server;
 import org.openstack4j.model.compute.Server.Status;
 import org.openstack4j.model.heat.Resource;
 import org.openstack4j.model.network.IP;
+import org.openstack4j.model.network.IPVersionType;
 import org.openstack4j.model.network.Network;
 import org.openstack4j.model.network.NetworkType;
 import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.Subnet;
 import org.openstack4j.openstack.heat.domain.HeatResource;
 import org.openstack4j.openstack.heat.domain.HeatResource.Resources;
 import org.springframework.core.env.Environment;
@@ -449,6 +451,70 @@ public class HeatBridgeImplTest {
         verify(osClient, times(10)).getNetworkById(anyString());
     }
 
+    @Test
+    public void testUpdateNetworksToAai() throws HeatBridgeException {
+
+        Subnet subnet1 = mock(Subnet.class);
+        when(subnet1.getId()).thenReturn("test-subnet1-id");
+        when(subnet1.getName()).thenReturn("test-subnet1-name");
+        when(subnet1.isDHCPEnabled()).thenReturn(true);
+        when(subnet1.getGateway()).thenReturn("test-subnet1-gateway");
+        when(subnet1.getCidr()).thenReturn("test-subnet1-gateway");
+        when(subnet1.getIpVersion()).thenReturn(IPVersionType.V4);
+
+        Subnet subnet2 = mock(Subnet.class);
+        when(subnet2.getId()).thenReturn("test-subnet2-id");
+        when(subnet2.getName()).thenReturn("test-subnet2-name");
+        when(subnet2.isDHCPEnabled()).thenReturn(true);
+        when(subnet2.getGateway()).thenReturn("test-subnet1-gateway");
+        when(subnet2.getCidr()).thenReturn("test-subnet1-gateway");
+        when(subnet2.getIpVersion()).thenReturn(IPVersionType.V6);
+
+        when(osClient.getSubnetById(subnet1.getId())).thenReturn(subnet1);
+        when(osClient.getSubnetById(subnet2.getId())).thenReturn(subnet2);
+
+        List<String> subnetIds = Arrays.asList(subnet1.getId(), subnet2.getId());
+
+        // Arrange
+        Network network1 = mock(Network.class);
+        when(network1.getId()).thenReturn("test-network1-id");
+        when(network1.isShared()).thenReturn(true);
+        when(network1.isRouterExternal()).thenReturn(true);
+        when(network1.isAdminStateUp()).thenReturn(true);
+        when(network1.getProviderPhyNet()).thenReturn("sriov-network1");
+        when(network1.getName()).thenReturn("network1");
+        when(network1.getSubnets()).thenReturn(subnetIds);
+
+        Network network2 = mock(Network.class);
+        when(network2.getId()).thenReturn("test-network2-id");
+        when(network2.isShared()).thenReturn(true);
+        when(network2.isRouterExternal()).thenReturn(true);
+        when(network2.isAdminStateUp()).thenReturn(true);
+        when(network2.getProviderPhyNet()).thenReturn("sriov-network2");
+        when(network2.getName()).thenReturn("network2");
+        when(network2.getSubnets()).thenReturn(subnetIds);
+
+        String vnfId = "some-uuiid-of-the-vnf";
+        String vfModuleId = "some-uuiid-of-the-vf-module";
+
+        Subnet subnet = mock(Subnet.class);
+
+        List<Network> networks = Arrays.asList(network1, network2);
+
+        // Act #1
+        heatbridge.buildAddNetworksToAaiAction(vnfId, vfModuleId, networks);
+
+        // Assert #1
+        verify(transaction, times(2)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class));
+
+        // Act #2
+        heatbridge.buildAddNetworksToAaiAction(vnfId, vfModuleId, networks);
+
+        // Assert #2
+        verify(transaction, times(4)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class));
+
+    }
+
     @Test
     public void testUpdateVserverLInterfacesToAai_skipVlans() throws HeatBridgeException {
         // Arrange
index 64c4565..2efd74d 100644 (file)
@@ -80,4 +80,14 @@ public class CDSPropertiesImpl implements CDSProperties {
     public int getTimeout() {
         return Integer.parseInt(Objects.requireNonNull(UrnPropertiesReader.getVariable(TIMEOUT)));
     }
+
+    @Override
+    public boolean getUseSSL() {
+        return false;
+    }
+
+    @Override
+    public boolean getUseBasicAuth() {
+        return true;
+    }
 }
index 6831a65..92ed61d 100644 (file)
@@ -50,11 +50,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 public class SdncInputParametersProvider extends AbstractInputParametersProvider<GenericVnf> {
 
     private static final Logger LOGGER = LoggerFactory.getLogger(SdncInputParametersProvider.class);
-
     private static final String VNF_PARAMETERS_PATH = "$..vnf-parameters";
-
     private final SDNCClient sdncClient;
-
     private final ObjectMapper mapper;
 
     @Autowired
@@ -68,34 +65,12 @@ public class SdncInputParametersProvider extends AbstractInputParametersProvider
         final String vnfName = genericVnf.getVnfName();
         final String vnfType = getVnfType(genericVnf);
         final String url = getPreloadVnfsUrl(vnfName, vnfType);
+        final InputParameter inputParameter = parseInputParametersUsingUrl(url);
 
-        try {
-            LOGGER.debug("Will query sdnc for input parameters using url: {}", url);
-            final String jsonResponse = sdncClient.get(url);
-            final String json = JsonPathUtil.getInstance().locateResult(jsonResponse, VNF_PARAMETERS_PATH).orElse(null);
-
-            try {
-
-                if (json != null) {
-                    final List<VnfParameter> vnfParametersArray =
-                            mapper.readValue(json, new TypeReference<List<VnfParameter>>() {});
-                    final Map<String, String> vnfParametersMap = getVnfParameterMap(vnfParametersArray);
-                    final Map<String, String> additionalParameters = getAdditionalParameters(vnfParametersMap);
-                    final List<ExternalVirtualLink> extVirtualLinks = getExtVirtualLinks(vnfParametersMap);
-                    final InputParameter inputParameter = new InputParameter(additionalParameters, extVirtualLinks);
-                    LOGGER.info("InputParameter found in sdnc response : {}", inputParameter);
-                    return inputParameter;
-                }
-
-            } catch (final IOException exception) {
-                LOGGER.error("Unable to parse vnf parameters : {}", json, exception);
-            }
-        } catch (final Exception exception) {
-            LOGGER.error("Unable to retrieve/parse input parameters using URL: {} ", url, exception);
-        }
+        if (inputParameter != null)
+            return inputParameter;
         LOGGER.warn("No input parameters found ...");
         return NullInputParameter.NULL_INSTANCE;
-
     }
 
     private List<ExternalVirtualLink> getExtVirtualLinks(final Map<String, String> vnfParametersMap) {
@@ -109,19 +84,18 @@ public class SdncInputParametersProvider extends AbstractInputParametersProvider
 
     private Map<String, String> getAdditionalParameters(final Map<String, String> vnfParametersMap) {
         final String additionalParamsString = vnfParametersMap.get(ADDITIONAL_PARAMS);
+
         if (additionalParamsString != null && !additionalParamsString.isEmpty()) {
             return parseAdditionalParameters(additionalParamsString);
         }
         return Collections.emptyMap();
     }
 
-
     private Map<String, String> getVnfParameterMap(final List<VnfParameter> array) {
         if (array != null) {
             return array.stream().filter(vnfParam -> vnfParam.getName() != null && vnfParam.getValue() != null)
                     .collect(Collectors.toMap(VnfParameter::getName, VnfParameter::getValue));
         }
-
         return Collections.emptyMap();
     }
 
@@ -131,10 +105,43 @@ public class SdncInputParametersProvider extends AbstractInputParametersProvider
 
     private String getVnfType(final GenericVnf genericVnf) {
         final ModelInfoGenericVnf modelInfoGenericVnf = genericVnf.getModelInfoGenericVnf();
-        if (modelInfoGenericVnf != null && modelInfoGenericVnf.getModelName() != null) {
+        if (modelInfoGenericVnf != null) {
             return modelInfoGenericVnf.getModelName();
         }
         return genericVnf.getVnfType();
     }
 
+    private InputParameter parseInputParametersUsingUrl(String url) {
+        try {
+            LOGGER.debug("Will query sdnc for input parameters using url: {}", url);
+            final String jsonResponse = sdncClient.get(url);
+            final String json = JsonPathUtil.getInstance().locateResult(jsonResponse, VNF_PARAMETERS_PATH).orElse(null);
+            final InputParameter inputParameter = parseVnfParameters(json);
+
+            if (inputParameter != null)
+                return inputParameter;
+        } catch (final Exception exception) {
+            LOGGER.error("Unable to retrieve/parse input parameters using URL: {} ", url, exception);
+        }
+        return null;
+    }
+
+    private InputParameter parseVnfParameters(String json) {
+        try {
+            if (json != null) {
+                final List<VnfParameter> vnfParametersArray =
+                        mapper.readValue(json, new TypeReference<List<VnfParameter>>() {});
+                final Map<String, String> vnfParametersMap = getVnfParameterMap(vnfParametersArray);
+                final Map<String, String> additionalParameters = getAdditionalParameters(vnfParametersMap);
+                final List<ExternalVirtualLink> extVirtualLinks = getExtVirtualLinks(vnfParametersMap);
+                final InputParameter inputParameter = new InputParameter(additionalParameters, extVirtualLinks);
+                LOGGER.info("InputParameter found in sdnc response : {}", inputParameter);
+                return inputParameter;
+            }
+
+        } catch (final IOException exception) {
+            LOGGER.error("Unable to parse vnf parameters : {}", json, exception);
+        }
+        return null;
+    }
 }
index ac939d0..bdd738b 100644 (file)
@@ -40,12 +40,12 @@ public class UserParamInputParametersProvider extends AbstractInputParametersPro
             final InputParameter inputParameter = new InputParameter();
             final Object additionalParams = userParams.get(ADDITIONAL_PARAMS);
 
-            if (additionalParams != null && additionalParams instanceof String) {
+            if (additionalParams instanceof String) {
                 inputParameter.setAdditionalParams(parseAdditionalParameters(additionalParams.toString()));
             }
 
             final Object extVirtualLinks = userParams.get(EXT_VIRTUAL_LINKS);
-            if (extVirtualLinks != null && extVirtualLinks instanceof String) {
+            if (extVirtualLinks instanceof String) {
                 inputParameter.setExtVirtualLinks(parseExternalVirtualLinks(extVirtualLinks.toString()));
             }
             LOGGER.info("InputParameter found in userParams : {}", inputParameter);
index 0d45dad..2491c99 100644 (file)
@@ -35,30 +35,18 @@ public class VnfParameter {
     @JsonProperty("vnf-parameter-value")
     private String value;
 
-    /**
-     * @return the name
-     */
     public String getName() {
         return name;
     }
 
-    /**
-     * @param name the name to set
-     */
     public void setName(final String name) {
         this.name = name;
     }
 
-    /**
-     * @return the value
-     */
     public String getValue() {
         return value;
     }
 
-    /**
-     * @param value the value to set
-     */
     public void setValue(final String value) {
         this.value = value;
     }
@@ -66,10 +54,9 @@ public class VnfParameter {
     @Override
     public int hashCode() {
         final int prime = 31;
-        int result = 1;
-        result = prime * result + ((name == null) ? 0 : name.hashCode());
-        result = prime * result + ((value == null) ? 0 : value.hashCode());
-        return Objects.hash(name, value);
+        int nameResult = prime + ((name == null) ? 0 : name.hashCode());
+        int valueResult = prime + ((value == null) ? 0 : value.hashCode());
+        return Objects.hash(nameResult, valueResult);
     }
 
     @Override
@@ -78,7 +65,6 @@ public class VnfParameter {
             VnfParameter other = (VnfParameter) obj;
             return Objects.equals(name, other.name) && Objects.equals(value, other.value);
         }
-
         return false;
     }
 
@@ -86,5 +72,4 @@ public class VnfParameter {
     public String toString() {
         return "VnfParameter [name=" + name + ", value=" + value + "]";
     }
-
 }
index 985114a..9781f78 100644 (file)
@@ -146,6 +146,7 @@ public class WorkflowAction {
     private static final String VOLUMEGROUP_CREATE_PATTERN = "(A|C)(.*)Volume(.*)";
     private static final String CONTROLLER = "Controller";
     private static final String DEFAULT_CLOUD_OWNER = "org.onap.so.cloud-owner";
+    private static final String HOMING = "homing";
 
     @Autowired
     protected BBInputSetup bbInputSetup;
@@ -198,16 +199,12 @@ public class WorkflowAction {
             List<ExecuteBuildingBlock> flowsToExecute = new ArrayList<>();
 
             if (isRequestMacroServiceResume(isALaCarte, resourceType, requestAction, serviceInstanceId)) {
-                flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
-                if (flowsToExecute == null) {
-                    buildAndThrowException(execution, "Could not resume Macro flow. Error loading execution path.");
-                }
+                String errorMessage = "Could not resume Macro flow. Error loading execution path.";
+                flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
             } else if (isALaCarte && isResume) {
-                flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
-                if (flowsToExecute == null) {
-                    buildAndThrowException(execution,
-                            "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found");
-                }
+                String errorMessage =
+                        "Could not resume request with request Id: " + requestId + ". No flowsToExecute was found";
+                flowsToExecute = loadExecuteBuildingBlocks(execution, requestId, errorMessage);
             } else {
                 String vnfType = (String) execution.getVariable(VNF_TYPE);
                 String cloudOwner = getCloudOwner(requestDetails.getCloudConfiguration());
@@ -228,44 +225,19 @@ public class WorkflowAction {
                             || requestAction.equalsIgnoreCase(REPLACEINSTANCERETAINASSIGNMENTS))
                             && resourceType.equals(WorkflowType.VFMODULE)) {
                         logger.debug("Build a BB list for replacing BB modules");
-                        orchFlows = getVfModuleReplaceBuildingBlocks(new ConfigBuildingBlocksDataObject()
-                                .setsIRequest(sIRequest).setOrchFlows(orchFlows).setRequestId(requestId)
-                                .setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
-                                .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
-                                .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails)
-                                .setExecution(execution).setReplaceInformation(replaceInfo));
-                        for (OrchestrationFlow orchFlow : orchFlows) {
-                            if (orchFlow.getFlowName().contains(CONFIGURATION)) {
-                                List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
-                                configOrchFlows.add(orchFlow);
-                                List<ExecuteBuildingBlock> configBuildingBlocks =
-                                        getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject()
-                                                .setsIRequest(sIRequest).setOrchFlows(configOrchFlows)
-                                                .setRequestId(requestId).setResourceKey(resourceKey)
-                                                .setApiVersion(apiVersion).setResourceId(resourceId)
-                                                .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
-                                                .setWorkflowResourceIds(workflowResourceIds)
-                                                .setRequestDetails(requestDetails).setExecution(execution)
-                                                .setReplaceInformation(replaceInfo));
-                                flowsToExecute.addAll(configBuildingBlocks);
-                            } else {
-                                ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey,
-                                        apiVersion, resourceId, requestAction, true, vnfType, workflowResourceIds,
-                                        requestDetails, false, null, null, false, replaceInfo);
-                                flowsToExecute.add(ebb);
-                            }
-                        }
+                        ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution,
+                                sIRequest, requestId, workflowResourceIds, requestDetails, requestAction, resourceId,
+                                vnfType, orchFlows, apiVersion, resourceKey, replaceInfo);
+                        orchFlows = getVfModuleReplaceBuildingBlocks(cbbdo);
+
+                        createBuildingBlocksForOrchFlows(execution, sIRequest, requestId, workflowResourceIds,
+                                requestDetails, requestAction, resourceId, flowsToExecute, vnfType, orchFlows,
+                                apiVersion, resourceKey, replaceInfo);
                     } else {
                         if (isConfiguration(orchFlows) && !requestAction.equalsIgnoreCase(CREATEINSTANCE)) {
-                            List<ExecuteBuildingBlock> configBuildingBlocks =
-                                    getConfigBuildingBlocks(new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest)
-                                            .setOrchFlows(orchFlows).setRequestId(requestId).setResourceKey(resourceKey)
-                                            .setApiVersion(apiVersion).setResourceId(resourceId)
-                                            .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
-                                            .setWorkflowResourceIds(workflowResourceIds)
-                                            .setRequestDetails(requestDetails).setExecution(execution));
-
-                            flowsToExecute.addAll(configBuildingBlocks);
+                            addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId,
+                                    workflowResourceIds, requestDetails, requestAction, resourceId, flowsToExecute,
+                                    vnfType, apiVersion, resourceKey, replaceInfo, orchFlows);
                         }
                         orchFlows =
                                 orchFlows.stream().filter(item -> !item.getFlowName().contains(FABRIC_CONFIGURATION))
@@ -287,10 +259,7 @@ public class WorkflowAction {
                         // SERVICE-MACRO-ASSIGN will always get user params with a
                         // service.
                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
-                            List<Map<String, Object>> userParams =
-                                    sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-                            containsService =
-                                    userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
+                            containsService = isContainsService(sIRequest);
                             if (containsService) {
                                 traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
                             }
@@ -306,10 +275,7 @@ public class WorkflowAction {
                         // queries the SI and finds a VNF, macro fails.
 
                         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
-                            List<Map<String, Object>> userParams =
-                                    sIRequest.getRequestDetails().getRequestParameters().getUserParams();
-                            containsService =
-                                    userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
+                            containsService = isContainsService(sIRequest);
                         }
                         if (containsService) {
                             foundRelated = traverseUserParamsService(execution, resourceList, sIRequest, requestAction);
@@ -330,7 +296,7 @@ public class WorkflowAction {
                     } else if (resourceType == WorkflowType.SERVICE
                             && "deactivateInstance".equalsIgnoreCase(requestAction)) {
                         resourceList.add(new Resource(WorkflowType.SERVICE, "", false));
-                    } else if (resourceType == WorkflowType.VNF && ("replaceInstance".equalsIgnoreCase(requestAction)
+                    } else if (resourceType == WorkflowType.VNF && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
                             || ("recreateInstance".equalsIgnoreCase(requestAction)))) {
                         traverseAAIVnf(execution, resourceList, workflowResourceIds.getServiceInstanceId(),
                                 workflowResourceIds.getVnfId(), aaiResourceIds);
@@ -343,15 +309,15 @@ public class WorkflowAction {
                                 (int) resourceList.stream().filter(x -> type.equals(x.getResourceType())).count())
                                 .append("    ");
                     }
-                    logger.info("Found {}", foundObjects.toString());
+                    logger.info("Found {}", foundObjects);
 
                     if (orchFlows == null || orchFlows.isEmpty()) {
                         orchFlows = queryNorthBoundRequestCatalogDb(execution, requestAction, resourceType, isALaCarte,
                                 cloudOwner, serviceType);
                     }
                     boolean vnfReplace = false;
-                    if (resourceType.equals(WorkflowType.VNF) && ("replaceInstance".equalsIgnoreCase(requestAction)
-                            || "replaceInstanceRetainAssignments".equalsIgnoreCase(requestAction))) {
+                    if (resourceType.equals(WorkflowType.VNF) && (REPLACEINSTANCE.equalsIgnoreCase(requestAction)
+                            || REPLACEINSTANCERETAINASSIGNMENTS.equalsIgnoreCase(requestAction))) {
                         vnfReplace = true;
                     }
                     flowsToExecute = buildExecuteBuildingBlockList(orchFlows, resourceList, requestId, apiVersion,
@@ -364,7 +330,7 @@ public class WorkflowAction {
                     if (resourceType == WorkflowType.SERVICE
                             && (requestAction.equals(CREATEINSTANCE) || requestAction.equals(ASSIGNINSTANCE))
                             && resourceList.stream().anyMatch(x -> WorkflowType.VNF.equals(x.getResourceType()))) {
-                        execution.setVariable("homing", true);
+                        execution.setVariable(HOMING, true);
                         execution.setVariable("calledHoming", false);
                     }
                     if (resourceType == WorkflowType.SERVICE && (requestAction.equalsIgnoreCase(ASSIGNINSTANCE)
@@ -380,11 +346,10 @@ public class WorkflowAction {
             // enable it.
             if (sIRequest.getRequestDetails().getRequestParameters() != null
                     && sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
-                List<Map<String, Object>> userParams =
-                        sIRequest.getRequestDetails().getRequestParameters().getUserParams();
+                List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
                 for (Map<String, Object> params : userParams) {
                     if (params.containsKey(HOMINGSOLUTION)) {
-                        execution.setVariable("homing", !"none".equals(params.get(HOMINGSOLUTION)));
+                        execution.setVariable(HOMING, !"none".equals(params.get(HOMINGSOLUTION)));
                     }
                 }
             }
@@ -404,12 +369,7 @@ public class WorkflowAction {
             if (!isResume) {
                 bbInputSetupUtils.persistFlowExecutionPath(requestId, flowsToExecute);
             }
-            execution.setVariable("flowNames", flowNames);
-            execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
-            execution.setVariable("retryCount", 0);
-            execution.setVariable("isRollback", false);
-            execution.setVariable("flowsToExecute", flowsToExecute);
-            execution.setVariable("isRollbackComplete", false);
+            setExecutionVariables(execution, flowsToExecute, flowNames);
 
         } catch (Exception ex) {
             if (!(execution.hasVariable("WorkflowException")
@@ -421,6 +381,85 @@ public class WorkflowAction {
         }
     }
 
+    private void setExecutionVariables(DelegateExecution execution, List<ExecuteBuildingBlock> flowsToExecute,
+            List<String> flowNames) {
+        execution.setVariable("flowNames", flowNames);
+        execution.setVariable(BBConstants.G_CURRENT_SEQUENCE, 0);
+        execution.setVariable("retryCount", 0);
+        execution.setVariable("isRollback", false);
+        execution.setVariable("flowsToExecute", flowsToExecute);
+        execution.setVariable("isRollbackComplete", false);
+    }
+
+    private boolean isContainsService(ServiceInstancesRequest sIRequest) {
+        boolean containsService;
+        List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
+        containsService = userParams.stream().anyMatch(param -> param.containsKey(USERPARAMSERVICE));
+        return containsService;
+    }
+
+    private List<Map<String, Object>> getListOfUserParams(ServiceInstancesRequest sIRequest) {
+        return sIRequest.getRequestDetails().getRequestParameters().getUserParams();
+    }
+
+    private List<ExecuteBuildingBlock> loadExecuteBuildingBlocks(DelegateExecution execution, String requestId,
+            String errorMessage) {
+        List<ExecuteBuildingBlock> flowsToExecute;
+        flowsToExecute = bbInputSetupUtils.loadOriginalFlowExecutionPath(requestId);
+        if (flowsToExecute == null) {
+            buildAndThrowException(execution, errorMessage);
+        }
+        return flowsToExecute;
+    }
+
+    private ConfigBuildingBlocksDataObject createConfigBuildingBlocksDataObject(DelegateExecution execution,
+            ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
+            RequestDetails requestDetails, String requestAction, String resourceId, String vnfType,
+            List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
+            ReplaceInstanceRelatedInformation replaceInfo) {
+
+        return new ConfigBuildingBlocksDataObject().setsIRequest(sIRequest).setOrchFlows(orchFlows)
+                .setRequestId(requestId).setResourceKey(resourceKey).setApiVersion(apiVersion).setResourceId(resourceId)
+                .setRequestAction(requestAction).setaLaCarte(true).setVnfType(vnfType)
+                .setWorkflowResourceIds(workflowResourceIds).setRequestDetails(requestDetails).setExecution(execution)
+                .setReplaceInformation(replaceInfo);
+    }
+
+    private void createBuildingBlocksForOrchFlows(DelegateExecution execution, ServiceInstancesRequest sIRequest,
+            String requestId, WorkflowResourceIds workflowResourceIds, RequestDetails requestDetails,
+            String requestAction, String resourceId, List<ExecuteBuildingBlock> flowsToExecute, String vnfType,
+            List<OrchestrationFlow> orchFlows, String apiVersion, Resource resourceKey,
+            ReplaceInstanceRelatedInformation replaceInfo) throws Exception {
+
+        for (OrchestrationFlow orchFlow : orchFlows) {
+            if (orchFlow.getFlowName().contains(CONFIGURATION)) {
+                List<OrchestrationFlow> configOrchFlows = new ArrayList<>();
+                configOrchFlows.add(orchFlow);
+                addConfigBuildingBlocksToFlowsToExecuteList(execution, sIRequest, requestId, workflowResourceIds,
+                        requestDetails, requestAction, resourceId, flowsToExecute, vnfType, apiVersion, resourceKey,
+                        replaceInfo, configOrchFlows);
+            } else {
+                ExecuteBuildingBlock ebb = buildExecuteBuildingBlock(orchFlow, requestId, resourceKey, apiVersion,
+                        resourceId, requestAction, true, vnfType, workflowResourceIds, requestDetails, false, null,
+                        null, false, replaceInfo);
+                flowsToExecute.add(ebb);
+            }
+        }
+    }
+
+    private void addConfigBuildingBlocksToFlowsToExecuteList(DelegateExecution execution,
+            ServiceInstancesRequest sIRequest, String requestId, WorkflowResourceIds workflowResourceIds,
+            RequestDetails requestDetails, String requestAction, String resourceId,
+            List<ExecuteBuildingBlock> flowsToExecute, String vnfType, String apiVersion, Resource resourceKey,
+            ReplaceInstanceRelatedInformation replaceInfo, List<OrchestrationFlow> configOrchFlows) throws Exception {
+
+        ConfigBuildingBlocksDataObject cbbdo = createConfigBuildingBlocksDataObject(execution, sIRequest, requestId,
+                workflowResourceIds, requestDetails, requestAction, resourceId, vnfType, configOrchFlows, apiVersion,
+                resourceKey, replaceInfo);
+        List<ExecuteBuildingBlock> configBuildingBlocks = getConfigBuildingBlocks(cbbdo);
+        flowsToExecute.addAll(configBuildingBlocks);
+    }
+
     private Resource getResourceKey(ServiceInstancesRequest sIRequest, WorkflowType resourceType) {
         String resourceId = "";
         ModelInfo modelInfo = sIRequest.getRequestDetails().getModelInfo();
@@ -847,7 +886,7 @@ public class WorkflowAction {
         CollectionNetworkResourceCustomization collectionNetworkResourceCust =
                 getCollectionNetworkResourceCustomization(collectionResourceCustomization, instanceGroup);
         for (int i = 0; i < minNetworks; i++) {
-            if (collectionNetworkResourceCust != null && collectionInstCust != null) {
+            if (collectionNetworkResourceCust != null) {
                 Resource resource = new Resource(WorkflowType.VIRTUAL_LINK,
                         collectionNetworkResourceCust.getModelCustomizationUUID(), false);
                 resource.setVirtualLinkKey(Integer.toString(i));
@@ -1092,7 +1131,7 @@ public class WorkflowAction {
         String vnfCustomizationUUID = "";
         String vfModuleCustomizationUUID = "";
         if (sIRequest.getRequestDetails().getRequestParameters().getUserParams() != null) {
-            List<Map<String, Object>> userParams = sIRequest.getRequestDetails().getRequestParameters().getUserParams();
+            List<Map<String, Object>> userParams = getListOfUserParams(sIRequest);
             for (Map<String, Object> params : userParams) {
                 if (params.containsKey(USERPARAMSERVICE)) {
                     ObjectMapper obj = new ObjectMapper();
@@ -1120,14 +1159,12 @@ public class WorkflowAction {
                                                 && vfModuleCustomization.getVolumeHeatEnv() != null) {
                                             resourceList.add(new Resource(WorkflowType.VOLUMEGROUP,
                                                     vfModuleCustomization.getModelCustomizationUUID(), false));
-                                            foundRelated = true;
                                             foundVfModuleOrVG = true;
                                         }
 
                                         if (vfModuleCustomization.getVfModule() != null
                                                 && vfModuleCustomization.getVfModule().getModuleHeatTemplate() != null
                                                 && vfModuleCustomization.getHeatEnvironment() != null) {
-                                            foundRelated = true;
                                             foundVfModuleOrVG = true;
                                             Resource resource = new Resource(WorkflowType.VFMODULE,
                                                     vfModuleCustomization.getModelCustomizationUUID(), false);
@@ -1744,7 +1781,7 @@ public class WorkflowAction {
     private void fillExecution(DelegateExecution execution, boolean suppressRollback, String resourceId,
             WorkflowType resourceType) {
         execution.setVariable("sentSyncResponse", false);
-        execution.setVariable("homing", false);
+        execution.setVariable(HOMING, false);
         execution.setVariable("calledHoming", false);
         execution.setVariable(BBConstants.G_ISTOPLEVELFLOW, true);
         execution.setVariable("suppressRollback", suppressRollback);
index 6254aae..bc32489 100644 (file)
@@ -39,13 +39,12 @@ public class HomingListener implements FlowManipulator {
     public void run(List<ExecuteBuildingBlock> flowsToExecute, ExecuteBuildingBlock currentBB,
             BuildingBlockExecution execution) {
 
-        boolean homing = (boolean) execution.getVariable("homing");
-        boolean calledHoming = (boolean) execution.getVariable("calledHoming");
+        boolean homing = execution.getVariable("homing");
+        boolean calledHoming = execution.getVariable("calledHoming");
         if (homing && !calledHoming) {
             currentBB.setHoming(true);
             execution.setVariable("calledHoming", true);
         }
     }
 
-
 }
diff --git a/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/listeners/HomingListenerTest.java b/bpmn/so-bpmn-tasks/src/test/java/org/onap/so/bpmn/infrastructure/workflow/tasks/listeners/HomingListenerTest.java
new file mode 100644 (file)
index 0000000..d238318
--- /dev/null
@@ -0,0 +1,59 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Nokia
+ * ================================================================================
+ * 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.bpmn.infrastructure.workflow.tasks.listeners;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import org.camunda.bpm.engine.delegate.DelegateExecution;
+import org.camunda.bpm.extension.mockito.delegate.DelegateExecutionFake;
+import org.junit.Test;
+import org.onap.so.bpmn.common.BuildingBlockExecution;
+import org.onap.so.bpmn.common.DelegateExecutionImpl;
+import org.onap.so.bpmn.servicedecomposition.entities.ExecuteBuildingBlock;
+
+public class HomingListenerTest {
+
+    private static final String CALLED_HOMING = "calledHoming";
+
+    @Test
+    public void shouldRunForAssignVnfBB() {
+        assertThat(new HomingListener().shouldRunFor("AssignVnfBB", false, null)).isTrue();
+    }
+
+    @Test
+    public void shouldNotRunForDifferentThanAssignVnfBB() {
+        assertThat(new HomingListener().shouldRunFor("someDifferentBB", false, null)).isFalse();
+    }
+
+    @Test
+    public void runWithHoming() {
+        // given
+        DelegateExecution execution = new DelegateExecutionFake();
+        execution.setVariable("homing", true);
+        execution.setVariable(CALLED_HOMING, false);
+        BuildingBlockExecution buildingBlockExecution = new DelegateExecutionImpl(execution);
+        ExecuteBuildingBlock executeBuildingBlock = new ExecuteBuildingBlock();
+        // when
+        new HomingListener().run(null, executeBuildingBlock, buildingBlockExecution);
+        // then
+        assertThat(executeBuildingBlock.isHoming()).isTrue();
+        assertThat((boolean) buildingBlockExecution.getVariable(CALLED_HOMING)).isTrue();
+    }
+}
index 4223e0a..24baad7 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0"?>
+<?xml version="1.0" ?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
       </plugin>
     </plugins>
   </build>
-</project>
+</project>
\ No newline at end of file
diff --git a/common/src/main/java/org/onap/so/client/KeyStoreLoader.java b/common/src/main/java/org/onap/so/client/KeyStoreLoader.java
new file mode 100644 (file)
index 0000000..8279be8
--- /dev/null
@@ -0,0 +1,48 @@
+/*-
+ * ============LICENSE_START=======================================================
+ * ONAP - SO
+ * ================================================================================
+ * Copyright (C) 2020 Deutsche Telekom.
+ * ================================================================================
+ * 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.client;
+
+import java.io.FileInputStream;
+import java.nio.file.Paths;
+import java.security.KeyStore;
+
+public abstract class KeyStoreLoader {
+
+    static final String SSL_KEY_STORE_KEY = "javax.net.ssl.keyStore";
+
+    static public KeyStore getKeyStore() {
+        KeyStore ks = null;
+        final char[] password = getSSlKeyStorePassword().toCharArray();
+        try (FileInputStream fis =
+                new FileInputStream(Paths.get(System.getProperty(SSL_KEY_STORE_KEY)).normalize().toString())) {
+            ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(fis, password);
+        } catch (final Exception e) {
+            return null;
+        }
+
+        return ks;
+    }
+
+    static public String getSSlKeyStorePassword() {
+        return System.getProperty("javax.net.ssl.keyStorePassword");
+    }
+}
index f5737b8..1e89538 100644 (file)
@@ -20,9 +20,7 @@
 
 package org.onap.so.client;
 
-import java.io.FileInputStream;
 import java.net.URI;
-import java.nio.file.Paths;
 import java.security.KeyStore;
 import java.security.NoSuchAlgorithmException;
 import java.util.Optional;
@@ -33,10 +31,8 @@ import javax.ws.rs.client.ClientBuilder;
 public abstract class RestClientSSL extends RestClient {
 
     private static final String TRUE = "true";
-    private static final String SSL_KEY_STORE_KEY = "javax.net.ssl.keyStore";
     private static final String MSO_LOAD_SSL_CLIENT_KEYSTORE_KEY = "mso.load.ssl.client.keystore";
 
-
     protected RestClientSSL(RestProperties props, Optional<URI> path) {
         super(props, path);
     }
@@ -52,9 +48,9 @@ public abstract class RestClientSSL extends RestClient {
         try {
             String loadSSLKeyStore = System.getProperty(RestClientSSL.MSO_LOAD_SSL_CLIENT_KEYSTORE_KEY);
             if (loadSSLKeyStore != null && loadSSLKeyStore.equalsIgnoreCase(TRUE)) {
-                KeyStore ks = getKeyStore();
+                KeyStore ks = KeyStoreLoader.getKeyStore();
                 if (ks != null) {
-                    client = ClientBuilder.newBuilder().keyStore(ks, getSSlKeyStorePassword()).build();
+                    client = ClientBuilder.newBuilder().keyStore(ks, KeyStoreLoader.getSSlKeyStorePassword()).build();
                     logger.info("RestClientSSL not using default SSL context - setting keystore here.");
                     return client;
                 }
@@ -67,23 +63,4 @@ public abstract class RestClientSSL extends RestClient {
         }
         return client;
     }
-
-    private KeyStore getKeyStore() {
-        KeyStore ks = null;
-        char[] password = getSSlKeyStorePassword().toCharArray();
-        try (FileInputStream fis = new FileInputStream(
-                Paths.get(System.getProperty(RestClientSSL.SSL_KEY_STORE_KEY)).normalize().toString())) {
-            ks = KeyStore.getInstance(KeyStore.getDefaultType());
-
-            ks.load(fis, password);
-        } catch (Exception e) {
-            return null;
-        }
-
-        return ks;
-    }
-
-    private String getSSlKeyStorePassword() {
-        return System.getProperty("javax.net.ssl.keyStorePassword");
-    }
 }
index 7ef1589..fa309b5 100644 (file)
@@ -2,7 +2,7 @@
  * ============LICENSE_START=======================================================
  * ONAP - SO
  * ================================================================================
- * Copyright (C) 2017 - 2019 Bell Canada.
+ * Copyright (C) 2017 - 2019 Bell Canada, Deutsche Telekom.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,9 +23,16 @@ package org.onap.so.client.cds;
 import io.grpc.ManagedChannel;
 import io.grpc.internal.DnsNameResolverProvider;
 import io.grpc.internal.PickFirstLoadBalancerProvider;
+import io.grpc.netty.GrpcSslContexts;
 import io.grpc.netty.NettyChannelBuilder;
+import java.security.KeyStore;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
 import java.util.concurrent.CountDownLatch;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.TrustManagerFactory;
 import org.onap.ccsdk.cds.controllerblueprints.processing.api.ExecutionServiceInput;
+import org.onap.so.client.KeyStoreLoader;
 import org.onap.so.client.PreconditionFailedException;
 import org.onap.so.client.RestPropertiesLoader;
 import org.slf4j.Logger;
@@ -73,10 +80,36 @@ public class CDSProcessingClient implements AutoCloseable {
             throw new PreconditionFailedException(
                     "No RestProperty.CDSProperties implementation found on classpath, can't create client.");
         }
-        this.channel = NettyChannelBuilder.forAddress(props.getHost(), props.getPort())
+        NettyChannelBuilder builder = NettyChannelBuilder.forAddress(props.getHost(), props.getPort())
                 .nameResolverFactory(new DnsNameResolverProvider())
-                .loadBalancerFactory(new PickFirstLoadBalancerProvider())
-                .intercept(new BasicAuthClientInterceptor(props)).usePlaintext().build();
+                .loadBalancerFactory(new PickFirstLoadBalancerProvider());
+        if (props.getUseSSL()) {
+            log.info("Configure SSL connection");
+            KeyStore ks = KeyStoreLoader.getKeyStore();
+            if (ks == null) {
+                log.error("Can't load KeyStore");
+                throw new RuntimeException("Can't load KeyStore to create secure channel");
+            }
+            try {
+                TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+                tmf.init(ks);
+                builder.sslContext(GrpcSslContexts.forClient().trustManager(tmf).build());
+            } catch (NoSuchAlgorithmException e) {
+                log.error("Can't get default TrustManager algorithm");
+                throw new RuntimeException(e);
+            } catch (KeyStoreException e) {
+                log.error("TrustManagerFactory initialization failed");
+                throw new RuntimeException(e);
+            } catch (SSLException e) {
+                log.error("SslContext build error");
+                throw new RuntimeException(e);
+            }
+        }
+        if (props.getUseBasicAuth()) {
+            log.info("Configure Basic authentication");
+            builder.intercept(new BasicAuthClientInterceptor(props)).usePlaintext();
+        }
+        this.channel = builder.build();
         this.handler = new CDSProcessingHandler(listener);
         log.info("CDSProcessingClient started");
     }
index 37a5c0b..db566fa 100644 (file)
@@ -22,7 +22,6 @@ package org.onap.so.client.cds;
 
 import org.onap.so.client.RestProperties;
 
-
 public interface CDSProperties extends RestProperties {
 
     String getHost();
@@ -32,4 +31,8 @@ public interface CDSProperties extends RestProperties {
     String getBasicAuth();
 
     int getTimeout();
+
+    boolean getUseSSL();
+
+    boolean getUseBasicAuth();
 }
index 18ec9ef..5792c28 100644 (file)
@@ -20,7 +20,6 @@
 
 package org.onap.so.client.cds;
 
-
 import static org.junit.Assert.*;
 import static org.mockito.Mockito.*;
 import io.grpc.inprocess.InProcessChannelBuilder;
@@ -58,7 +57,6 @@ public class CDSProcessingClientTest {
     private CDSProcessingHandler handler;
     private CDSProcessingClient client;
 
-
     private final MutableHandlerRegistry serviceRegistry = new MutableHandlerRegistry();
     private final List<String> messagesDelivered = new ArrayList<>();
     private final CountDownLatch allRequestsDelivered = new CountDownLatch(1);
@@ -115,7 +113,6 @@ public class CDSProcessingClientTest {
         new CDSProcessingClient(listener);
     }
 
-
     @Test
     public void testSendMessageFail() throws Exception {
 
index 2834d37..41238e5 100644 (file)
@@ -72,4 +72,14 @@ public class TestCDSPropertiesImpl implements CDSProperties {
     public int getTimeout() {
         return 60;
     }
+
+    @Override
+    public boolean getUseSSL() {
+        return false;
+    }
+
+    @Override
+    public boolean getUseBasicAuth() {
+        return true;
+    }
 }
diff --git a/docs/developer_info/Working_with_so_monitoring.rst b/docs/developer_info/Working_with_so_monitoring.rst
new file mode 100644 (file)
index 0000000..18b6d94
--- /dev/null
@@ -0,0 +1,70 @@
+.. This work is licensed under a Creative Commons Attribution 4.0 International License.
+.. http://creativecommons.org/licenses/by/4.0
+.. Copyright 2017 Huawei Technologies Co., Ltd.
+
+Working with SO Monitoring
+==========================
+
+After the SO code is fully deployed, certain changes needs to be made in order to access the so-monitoring ui.
+
+1. Change the service type to NodePort
+---------------------------------------
+
+By default, the type of the so monitoring service is ClusterIP, which makes the Service only reachable from within the cluster.
+This is changed to NodePort, which is used to expose the service at a static port . Hence we will be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
+
+Command used to get the service configuration of so monitoring is:
+
+**sudo kubectl edit svc so-monitoring -n onap**
+
+.. image:: ../images/nodeport.png
+
+2. Add the credentials to login
+--------------------------------
+
+The override.yaml needs to be added with the login credentials, that is the username and the password in encrypted form.
+
+.. code-block:: bash
+
+ spring:
+   main:
+     allow-bean-definition-overriding: true
+   security:
+     usercredentials:
+     -                                         
+       username: gui
+       password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke'
+       role: GUI-Client
+
+This override.yaml can be directly edited in case of local setup using docker.
+
+When deploying in any environment  using OOM, then after deployment the configmap needs to be edited. As configmap is the one reading the override.yaml.
+
+**Note** : Before deployment , if we add these changes in override.yaml ,then it may give parsing error in configmap while deployment. And after deployment the permissions on override.yaml don't allow us to edit it. So the best option is to edit the configmap using the below command and restart the pod. 
+
+**kubectl -n onap edit configmap dev-so-monitoring-app-configmap**
+
+.. image:: ../images/configmap.png
+
+Special care needs to be given to the indentation. spring needs to be inline with the mso already present and others added accordingly.
+
+3. Login to SO Monitoring
+-------------------------
+
+We need to first identify the external port which its mapped to using the following command : 
+
+**sudo kubectl -n onap get svc | grep so-monitoring**
+
+.. image:: ../images/nodemap.png
+
+Then access the UI of so monitoring , for example by  http://<IP>:30224/ 
+
+username : gui,
+password: password1$
+
+
+.. image:: ../images/ui.png
+
+
+
+
index 10ea836..63338de 100644 (file)
@@ -11,6 +11,7 @@ SO Developer Information
 
    Building_SO.rst
    Working_with_SO_Docker.rst
+   Working_with_so_monitoring.rst
    Camunda_Cockpit_Community_Edition.rst
    Camunda_Cockpit_Enterprise_Edition.rst
    Camunda_Modeler.rst
diff --git a/docs/images/configmap.png b/docs/images/configmap.png
new file mode 100644 (file)
index 0000000..3683de3
Binary files /dev/null and b/docs/images/configmap.png differ
diff --git a/docs/images/nodemap.png b/docs/images/nodemap.png
new file mode 100644 (file)
index 0000000..8dfda6c
Binary files /dev/null and b/docs/images/nodemap.png differ
diff --git a/docs/images/nodeport.png b/docs/images/nodeport.png
new file mode 100644 (file)
index 0000000..53bc02f
Binary files /dev/null and b/docs/images/nodeport.png differ
diff --git a/docs/images/ui.png b/docs/images/ui.png
new file mode 100644 (file)
index 0000000..1c075ba
Binary files /dev/null and b/docs/images/ui.png differ
diff --git a/pom.xml b/pom.xml
index ee9a352..68559c9 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -1,6 +1,5 @@
-<?xml version="1.0"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<?xml version="1.0" ?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.onap.oparent</groupId>
       </build>
     </profile>
   </profiles>
-</project>
+</project>
\ No newline at end of file
index c9b417b..66780c7 100644 (file)
@@ -53,7 +53,7 @@
           <configuration>
             <lifecycleMappingMetadata>
               <pluginExecutions>
-                  <pluginExecution>
+                <pluginExecution>
                   <pluginExecutionFilter>
                     <groupId>org.apache.maven.plugins</groupId>
                     <artifactId>maven-dependency-plugin</artifactId>
           <groupId>javax.ws.rs</groupId>
           <artifactId>jsr311-api</artifactId>
         </exclusion>
-               <exclusion>
+        <exclusion>
           <groupId>io.swagger</groupId>
           <artifactId>swagger-annotations</artifactId>
         </exclusion>
       <groupId>org.mariadb.jdbc</groupId>
       <artifactId>mariadb-java-client</artifactId>
     </dependency>
-     <dependency>
+    <dependency>
       <groupId>org.glassfish.jersey.core</groupId>
       <artifactId>jersey-common</artifactId>
     </dependency>