Merge "Create PServer/PInterface Objects in AAI based on openstack's stack resources"
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
index 9adcdcb..0d1d690 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/vnf/MsoVnfAdapterImpl.java
@@ -431,6 +431,8 @@
 
             List<Server> osServers = heatBridgeClient.getAllOpenstackServers(stackResources);
 
+            heatBridgeClient.createPserversAndPinterfacesIfNotPresentInAai(stackResources);
+
             List<Image> osImages = heatBridgeClient.extractOpenstackImagesFromServers(osServers);
 
             List<Flavor> osFlavors = heatBridgeClient.extractOpenstackFlavorsFromServers(osServers);
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java
index aebd04f..d568bc2 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java
@@ -138,6 +138,13 @@
     void buildAddVserverLInterfacesToAaiAction(List<Resource> stackResources, List<String> oobMgtNetIds);
 
     /**
+     * Query and build AAI actions for Openstack Compute resources to AAI's pserver and pinterface objects
+     *
+     * @param stackResources Openstack StackResources list
+     */
+    void createPserversAndPinterfacesIfNotPresentInAai(final List<Resource> stackResources) throws HeatBridgeException;
+
+    /**
      * Execute AAI restful API to update the Openstack resources
      *
      * @throws HeatBridgeException when failing to add openstack resource PoJos to AAI
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java
index ae15b70..a1b3305 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java
@@ -32,6 +32,7 @@
  */
 package org.onap.so.heatbridge;
 
+import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -49,6 +50,7 @@
 import org.onap.aai.domain.yang.L3InterfaceIpv4AddressList;
 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.SriovPf;
 import org.onap.aai.domain.yang.SriovPfs;
 import org.onap.aai.domain.yang.SriovVf;
@@ -63,6 +65,7 @@
 import org.onap.so.client.aai.entities.uri.AAIUriFactory;
 import org.onap.so.client.graphinventory.entities.uri.Depth;
 import org.onap.so.client.graphinventory.exceptions.BulkProcessFailed;
+import org.onap.so.client.PreconditionFailedException;
 import org.onap.so.db.catalog.beans.CloudIdentity;
 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
 import org.onap.so.heatbridge.factory.MsoCloudClientFactoryImpl;
@@ -263,6 +266,44 @@
         }
     }
 
+    @Override
+    public void createPserversAndPinterfacesIfNotPresentInAai(final List<Resource> stackResources)
+            throws HeatBridgeException {
+        Map<String, Pserver> serverHostnames = getPserverMapping(stackResources);
+        createPServerIfNotExists(serverHostnames);
+        List<String> portIds =
+                extractStackResourceIdsByResourceType(stackResources, HeatBridgeConstants.OS_PORT_RESOURCE_TYPE);
+        for (String portId : portIds) {
+            Port port = osClient.getPortById(portId);
+            if (port.getvNicType().equalsIgnoreCase(HeatBridgeConstants.OS_SRIOV_PORT_TYPE)) {
+                createPServerPInterfaceIfNotExists(serverHostnames.get(port.getHostId()).getHostname(),
+                        aaiHelper.buildPInterface(port));
+            }
+        }
+    }
+
+    private Map<String, Pserver> getPserverMapping(final List<Resource> stackResources) {
+        List<Server> osServers = getAllOpenstackServers(stackResources);
+        Map<String, Pserver> pserverMap = new HashMap<>();
+        for (Server server : osServers) {
+            pserverMap.put(server.getHost(), aaiHelper.buildPserver(server));
+        }
+        return pserverMap;
+    }
+
+    private void createPServerIfNotExists(Map<String, Pserver> serverHostnames) {
+        for (Pserver pserver : serverHostnames.values()) {
+            AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.PSERVER, pserver.getHostname());
+            resourcesClient.createIfNotExists(uri, Optional.of(pserver));
+        }
+    }
+
+    private void createPServerPInterfaceIfNotExists(String pserverHostname, PInterface pInterface) {
+        AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.P_INTERFACE, pserverHostname,
+                pInterface.getInterfaceName());
+        resourcesClient.createIfNotExists(uri, Optional.of(pInterface));
+    }
+
     private void updateLInterfaceVlan(final Port port, final LInterface lIf) {
         Vlan vlan = new Vlan();
         Network network = osClient.getNetworkById(port.getNetworkId());
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java
index f2d61d2..0e87e1f 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/constants/HeatBridgeConstants.java
@@ -43,6 +43,7 @@
     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";
+    public static final String OS_PHYSICAL_INTERFACE_KEY = "physical-interface";
     public static final String OS_VLAN_NETWORK_KEY = "vlan";
     public static final String OS_UNKNOWN_KEY = "unknown";
     public static final String OS_RESOURCES_SELF_LINK_KEY = "self";
diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java
index d8a8760..c578b29 100644
--- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java
+++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/helpers/AaiHelper.java
@@ -43,6 +43,8 @@
 import org.apache.commons.collections.CollectionUtils;
 import org.onap.aai.domain.yang.Flavor;
 import org.onap.aai.domain.yang.Image;
+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.RelationshipData;
 import org.onap.aai.domain.yang.RelationshipList;
@@ -50,6 +52,7 @@
 import org.onap.aai.domain.yang.Vserver;
 import org.onap.so.heatbridge.constants.HeatBridgeConstants;
 import org.openstack4j.model.compute.Server;
+import org.openstack4j.model.network.Port;
 
 /**
  * This class provides wrapper methods to manage creation of AAI objects and extracting objects from AAI and
@@ -137,6 +140,37 @@
     }
 
     /**
+     * Transform Openstack Server object to AAI Pserver object
+     *
+     * @param server Openstack server object
+     * @return AAI Pserver object
+     */
+    public Pserver buildPserver(final Server server) {
+        Pserver pserver = new Pserver();
+        pserver.setInMaint(false);
+        pserver.setPserverId(server.getId());
+        pserver.setHostname(server.getHypervisorHostname());
+        pserver.setPserverName2(server.getHost());
+        pserver.setProvStatus(server.getStatus().value());
+        return pserver;
+    }
+
+    /**
+     * Transform Openstack Server object to AAI PInterface object
+     *
+     * @param port Openstack port object
+     * @return AAI PInterface object
+     */
+    public PInterface buildPInterface(Port port) {
+        Map<String, Object> portProfile = port.getProfile();
+        PInterface pInterface = new PInterface();
+        pInterface.setInterfaceName(portProfile.get(HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY).toString());
+        pInterface.setInMaint(false);
+        pInterface.setInterfaceRole(HeatBridgeConstants.OS_PHYSICAL_INTERFACE_KEY);
+        return pInterface;
+    }
+
+    /**
      * Transform Openstack Image object to AAI Image object
      *
      * @param image Openstack Image object