From b2e9556678bbacd8c3777973b9fa89b63497e026 Mon Sep 17 00:00:00 2001 From: "Leigh, Phillip (pl876u)" Date: Fri, 8 Feb 2019 16:23:27 -0500 Subject: Handle L-Interface in AaiCtxBuilder Also adapted the sprintframework to aaiCtxBuilder and added more junit test cases Issue-ID: LOG-766 Change-Id: Ibcc81e7ad3602666ff17c660d33b9ab7b57620df Signed-off-by: Leigh, Phillip (pl876u) --- .../aai/datatype/LInterfaceInstance.java | 226 ++++++++++++++++++++ .../pomba/contextbuilder/aai/datatype/Vserver.java | 9 + .../aai/service/rs/RestServiceImpl.java | 2 + .../pomba/contextbuilder/aai/util/RestUtil.java | 153 +++++++++++++- .../LInterfaceInstanceTest.java | 80 +++++++ .../test/RestServiceTest.java | 230 +++++++++++++++++++++ src/test/resources/junit/aai-vserver-set3.json | 110 ++++++++++ src/test/resources/junit/l-interface-input.json | 10 + src/test/resources/junit/l-interface-input2.json | 10 + 9 files changed, 827 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/onap/pomba/contextbuilder/aai/datatype/LInterfaceInstance.java create mode 100644 src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/LInterfaceInstanceTest.java create mode 100644 src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/test/RestServiceTest.java create mode 100644 src/test/resources/junit/aai-vserver-set3.json create mode 100644 src/test/resources/junit/l-interface-input.json create mode 100644 src/test/resources/junit/l-interface-input2.json diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/LInterfaceInstance.java b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/LInterfaceInstance.java new file mode 100644 index 0000000..db992b1 --- /dev/null +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/LInterfaceInstance.java @@ -0,0 +1,226 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ + +package org.onap.pomba.contextbuilder.aai.datatype; + + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.onap.pomba.contextbuilder.aai.exception.AuditError; +import org.onap.pomba.contextbuilder.aai.exception.AuditException; + +public class LInterfaceInstance { + + @SerializedName("interface-id") + @Expose + private String interfaceId; + + @SerializedName("interface-name") + @Expose + private String interfaceName; + @SerializedName("interface-role") + @Expose + private String interfaceRole; + @SerializedName("is-port-mirrored") + @Expose + private String isPortMirrored; + @SerializedName("admin-status") + @Expose + private String adminStatus; + @SerializedName("network-name") + @Expose + private String networkName; + @SerializedName("macaddr") + @Expose + private String macAddr; + @SerializedName("in-maint") + @Expose + private String inMaint; + + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); + + public String toJson() { + return gson.toJson(this); + } + + public String getInterfaceId() { + return interfaceId; + } + + public void setInterfaceId(String interfaceId) { + this.interfaceId = interfaceId; + } + + public String getInterfaceName() { + return interfaceName; + } + + public void setInterfaceName(String interfaceName) { + this.interfaceName = interfaceName; + } + + public String getInterfaceRole() { + return interfaceRole; + } + + public void setInterfaceRole(String interfaceRole) { + this.interfaceRole = interfaceRole; + } + + public String getIsPortMirrored() { + return isPortMirrored; + } + + public void setIsPortMirrored(String isPortMirrored) { + this.isPortMirrored = isPortMirrored; + } + + public String getAdminStatus() { + return adminStatus; + } + + public void setAdminStatus(String adminStatus) { + this.adminStatus = adminStatus; + } + + public String getNetworkName() { + return networkName; + } + + public void setNetworkName(String networkName) { + this.networkName = networkName; + } + + public String getMacAddr() { + return macAddr; + } + + public void setMacAddr(String macAddr) { + this.macAddr = macAddr; + } + + public String getInMaint() { + return inMaint; + } + + public void setInMaint(String inMaint) { + this.inMaint = inMaint; + } + + public static LInterfaceInstance fromJson(String payload) throws AuditException { + try { + if (payload == null || payload.isEmpty()) { + throw new AuditException("Empty Json response"); + } + return gson.fromJson(payload, LInterfaceInstance.class); + } catch (Exception ex) { + throw new AuditException(AuditError.JSON_READER_PARSE_ERROR, ex); + } + } + + /** + * No args constructor for use in serialization + * + */ + public LInterfaceInstance() { + } + + /** + * + * @param interfaceId + * @param interfaceName + * @param interfaceRole + * @param isPortMirrored + * @param adminStatus + * @param networkName + * @param macAddr + * @param inMaint + * + */ + public LInterfaceInstance(String interfaceId, String interfaceName, String interfaceRole, + String isPortMirrored, String adminStatus, String networkName, + String macAddr,String inMaint + ) { + super(); + this.interfaceId = interfaceId; + this.interfaceName = interfaceName; + this.interfaceRole = interfaceRole; + this.isPortMirrored = isPortMirrored; + this.adminStatus = adminStatus; + this.networkName = networkName; + this.macAddr = macAddr; + this.inMaint = inMaint; + } + + + + /////////// common functions ////////////////////// + @Override + public String toString() { + return new ToStringBuilder(this) + .append("interfaceId", interfaceId) + .append("interfaceName", interfaceName) + .append("interfaceRole", interfaceRole) + .append("isPortMirrored", isPortMirrored) + .append("adminStatus", adminStatus) + .append("networkName", networkName) + .append("macAddr", macAddr) + .append("inMaint", inMaint) + .toString(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder() + .append(interfaceId) + .append(interfaceName) + .append(interfaceRole) + .append(isPortMirrored) + .append(adminStatus) + .append(networkName) + .append(macAddr) + .append(inMaint) + .toHashCode(); + } + + @Override + public boolean equals(Object other) { + if (other == this) { + return true; + } + if (!(other instanceof LInterfaceInstance)) { + return false; + } + LInterfaceInstance rhs = ((LInterfaceInstance) other); + return new EqualsBuilder() + .append(interfaceId, rhs.interfaceId) + .append(interfaceName, rhs.interfaceName) + .append(interfaceRole, rhs.interfaceRole) + .append(isPortMirrored, rhs.isPortMirrored) + .append(adminStatus, rhs.adminStatus) + .append(networkName, rhs.networkName) + .append(macAddr, rhs.macAddr) + .append(inMaint, rhs.inMaint) + .isEquals(); + } +} diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java index d7b8896..803e65d 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/datatype/Vserver.java @@ -62,6 +62,7 @@ public class Vserver { private RelationshipList relationshipList; private List pserverInstanceList; + private List lInterfaceInstanceList; public List getPserverInstanceList() { return pserverInstanceList; } @@ -70,6 +71,14 @@ public class Vserver { this.pserverInstanceList = pserverInstanceList; } + public List getlInterfaceInstanceList() { + return lInterfaceInstanceList; + } + + public void setlInterfaceInstanceList(List lInterfaceInstanceList) { + this.lInterfaceInstanceList = lInterfaceInstanceList; + } + private static final Gson gson = new GsonBuilder().disableHtmlEscaping().create(); public String toJson() { diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java index 7fd27fb..19e81df 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/rs/RestServiceImpl.java @@ -32,7 +32,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import java.util.UUID; +import org.springframework.stereotype.Component; +@Component public class RestServiceImpl implements RestService { private static Logger log = LoggerFactory.getLogger(RestService.class); private static final String EMPTY_JSON_STRING = "{}"; diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java b/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java index 0d09eb4..e3a1b15 100644 --- a/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java +++ b/src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java @@ -53,6 +53,7 @@ import org.onap.pomba.contextbuilder.aai.datatype.Vserver; import org.onap.pomba.contextbuilder.aai.datatype.PserverInstance; import org.onap.pomba.contextbuilder.aai.datatype.PInterfaceInstance; import org.onap.pomba.contextbuilder.aai.datatype.L3networkInstance; +import org.onap.pomba.contextbuilder.aai.datatype.LInterfaceInstance; import org.onap.pomba.contextbuilder.aai.exception.AuditError; import org.onap.pomba.contextbuilder.aai.exception.AuditException; import org.slf4j.Logger; @@ -63,6 +64,8 @@ import org.onap.pomba.common.datatypes.PNF; import org.onap.pomba.common.datatypes.PInterface; import com.bazaarvoice.jolt.JsonUtils; import org.onap.pomba.common.datatypes.Pserver; +import org.onap.pomba.common.datatypes.LInterface; + public class RestUtil { @@ -87,10 +90,13 @@ public class RestUtil { private static final String CATALOG_IMAGE = "image"; private static final String CATALOG_PSERVER = "pserver"; private static final String CATALOG_L3_NETWORK = "l3-network"; + private static final String CATALOG_PNF = "pnf"; + private static final String CATALOG_L_INTERFACE = "l-interface"; + private static final String VF_MODULES = "vf-modules"; private static final String VF_MODULE = "vf-module"; - private static final String CATALOG_PNF = "pnf"; + // Relationship Json Path private static final String RELATIONSHIP_LIST = "relationship-list"; @@ -136,7 +142,10 @@ public class RestUtil { private static final String ATTRIBUTE_NETWORK_TECHNOLOGY = "networkTechnology"; private static final String ATTRIBUTE_PHYSICAL_NETWORK_NAME = "physicalNetworkName"; private static final String ATTRIBUTE_SHARED_NETWORK_BOOLEAN = "sharedNetworkBoolean"; - + private static final String ATTRIBUTE_IS_PORT_MIRRORED = "isPortMirrored"; + private static final String ATTRIBUTE_NETWORK_NAME = "networkName"; + private static final String ATTRIBUTE_MAC_ADDR = "macAddr"; + private static final String ATTRIBUTE_ADMIN_STATUS = "adminStatus"; /** @@ -482,7 +491,19 @@ public class RestUtil { } else { // Logic to Create the Vserver POJO object Vserver vserver = Vserver.fromJson(vserverPayload); - vserver.setPserverInstanceList(getPserverInfoFromAai(vserverPayload, aaiClient, baseURL, transactionId, aaiBasicAuthorization)); + + // add pserver if any + List pserverInstanceLst = getPserverInfoFromAai(vserverPayload, aaiClient, baseURL, transactionId, aaiBasicAuthorization); + if ((pserverInstanceLst != null) && (!pserverInstanceLst.isEmpty())) { + vserver.setPserverInstanceList(pserverInstanceLst); + } + + // add L-interface List if any + List lInterfaceInstanceLst = getLInterfaceInstanceInfoFromAai(vserverPayload, aaiClient, baseURL, transactionId, aaiBasicAuthorization); + if ((lInterfaceInstanceLst != null) && (!lInterfaceInstanceLst.isEmpty())) { + vserver.setlInterfaceInstanceList(lInterfaceInstanceLst); + } + vserverLst.add(vserver); } } @@ -532,6 +553,38 @@ public class RestUtil { return pserverLst; } + private static List getLInterfaceInstanceInfoFromAai (String vserverPayload, RestClient aaiClient, String baseURL, String transactionId, String aaiBasicAuthorization) throws AuditException { + if (vserverPayload == null) { + //already reported. + return null; + } + + //Obtain related L-Interface instance info + List lInterfaceRelatedLinkList = handleRelationshipGeneral (vserverPayload,CATALOG_L_INTERFACE ); + List lInterfaceLst = null; + if ((lInterfaceRelatedLinkList == null) || (lInterfaceRelatedLinkList.isEmpty())){ + // already reported + return null; + } + lInterfaceLst = new ArrayList<>(); + for (String lInterfaceRelatedLink : lInterfaceRelatedLinkList) { + String lInterfaceURL = baseURL + lInterfaceRelatedLink + DEPTH;; + String lInterfacePayload = getResource(aaiClient, lInterfaceURL, aaiBasicAuthorization, transactionId, + MediaType.valueOf(MediaType.APPLICATION_XML)); + + if (isEmptyJson(lInterfacePayload)) { + log.info(LogMessages.NOT_FOUND, "L-INTERFACE with url", lInterfaceURL); + } else { + log.info("Message from AAI for L-INTERFACE %s ,message body: %s", lInterfaceURL,lInterfacePayload); + // Logic to Create the Pserver POJO object + LInterfaceInstance lInterfaceInstance = LInterfaceInstance.fromJson(lInterfacePayload); + + //update P-Interface if any. + lInterfaceLst.add(lInterfaceInstance); + } + } + return lInterfaceLst; + } private static String getVnfId(String genericVNFPayload) throws AuditException { @@ -682,6 +735,17 @@ public class RestUtil { pServer = getPserverInfo (pserverInstanceList); } vm.setPServer(pServer); + + //Update L-Interface here + List lInterfaceInstanceList = vserver.getlInterfaceInstanceList(); + List lInterfacelst = null; + if (lInterfaceInstanceList != null) { + lInterfacelst = getLInterfaceLstInfo (lInterfaceInstanceList); + } + if ((lInterfacelst != null) && (!lInterfacelst.isEmpty())) { + vm.setLInterfaceList(lInterfacelst); + } + vmList.add(vm); } @@ -835,6 +899,89 @@ public class RestUtil { return pserver; } + private static List getLInterfaceLstInfo (List lInterfaceInstanceList) { + if (lInterfaceInstanceList == null) { + return null; + } + + List lInterfaceLst = new ArrayList<>(); + + for (LInterfaceInstance lInterfaceInstance: lInterfaceInstanceList) { + LInterface lInterface = new LInterface(); + lInterface.setUuid(lInterfaceInstance.getInterfaceId()); + lInterface.setName(lInterfaceInstance.getInterfaceName()); + + List attributeList = new ArrayList<>(); + // Iterate through the ENUM Attribute list + for (Attribute.Name name: Attribute.Name.values()) { + if ((name.name().equals(ATTRIBUTE_INTERFACE_ROLE)) + && isValid(lInterfaceInstance.getInterfaceRole())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.interfaceRole); + att.setValue(String.valueOf(lInterfaceInstance.getInterfaceRole())); + attributeList.add(att); + } + + if ((name.name().equals(ATTRIBUTE_IS_PORT_MIRRORED)) + && isValid(lInterfaceInstance.getIsPortMirrored())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.isPortMirrored); + att.setValue(String.valueOf(lInterfaceInstance.getIsPortMirrored())); + attributeList.add(att); + } + + if ((name.name().equals(ATTRIBUTE_ADMIN_STATUS )) + && isValid(lInterfaceInstance.getAdminStatus())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.adminStatus); + att.setValue(String.valueOf(lInterfaceInstance.getAdminStatus())); + attributeList.add(att); + } + + if ((name.name().equals(ATTRIBUTE_NETWORK_NAME )) + && isValid(lInterfaceInstance.getNetworkName())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.networkName); + att.setValue(String.valueOf(lInterfaceInstance.getNetworkName())); + attributeList.add(att); + } + + if ((name.name().equals(ATTRIBUTE_MAC_ADDR )) + && isValid(lInterfaceInstance.getMacAddr())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.macAddress); + att.setValue(String.valueOf(lInterfaceInstance.getMacAddr())); + attributeList.add(att); + } + + if ((name.name().equals(ATTRIBUTE_LOCKEDBOOLEAN)) + && isValid(lInterfaceInstance.getInMaint())){ + Attribute att = new Attribute(); + att.setDataQuality(DataQuality.ok()); + att.setName(Attribute.Name.lockedBoolean); + att.setValue(String.valueOf(lInterfaceInstance.getInMaint())); + attributeList.add(att); + } + + } + + if (!attributeList.isEmpty()) { + lInterface.setAttributes(attributeList); + } + lInterfaceLst.add(lInterface); + } + + if (lInterfaceLst.isEmpty()) { + return null; + } + return lInterfaceLst; + } + private static Pserver updatePserverInfoWithPInterface (Pserver pserver, List pInterfaceInstanceList) { List pInterfaceList = new ArrayList<>(); diff --git a/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/LInterfaceInstanceTest.java b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/LInterfaceInstanceTest.java new file mode 100644 index 0000000..dbca0d0 --- /dev/null +++ b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/LInterfaceInstanceTest.java @@ -0,0 +1,80 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.logging_analytics.pomba.pomba_aai_context_builder; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; +import org.onap.pomba.contextbuilder.aai.datatype.L3networkInstance; +import org.onap.pomba.contextbuilder.aai.datatype.LInterfaceInstance; + +public class LInterfaceInstanceTest { + @Test + public void testL3networkInstanceEquals() { + L3networkInstance l3networkInstance1 = new L3networkInstance + ( "networkId1", "networkName1", "networkType1", + "networkRole1", "networkTechnology1", "resourceVersion1", + "modelInvariantId1", "modelVersionId1", "physicalNetworkName1", "true", + null); + + L3networkInstance l3networkInstance2 = new L3networkInstance (); + l3networkInstance2.setNetworkId("networkId1"); + l3networkInstance2.setNetworkName("networkName1"); + l3networkInstance2.setNetworkType("networkType1"); + l3networkInstance2.setNetworkRole("networkRole1"); + l3networkInstance2.setNetworkTechnology("networkTechnology1"); + l3networkInstance2.setResourceVersion("resourceVersion1"); + l3networkInstance2.setModelInvariantId("modelInvariantId1"); + l3networkInstance2.setModelVersionId("modelVersionId1"); + l3networkInstance2.setPhysicalNetworkName("physicalNetworkName1"); + l3networkInstance2.setSharedNetworkBoolean("true"); + l3networkInstance2.setRelationshipList(null); + + l3networkInstance1.toJson(); + l3networkInstance1.toString(); + assertEquals("physicalNetworkName1", l3networkInstance2.getPhysicalNetworkName()); + assertTrue(l3networkInstance1.equals(l3networkInstance1)); + assertTrue(l3networkInstance1.equals(l3networkInstance2)); + } + + @Test + public void testLInterfaceInstanceEquals() { + LInterfaceInstance lInterfaceInstance1 = new LInterfaceInstance + ( "interfaceId1", "interfaceName1", "interfaceRole1", + "isPortMirrored1", "adminStatus1", "networkName1", + "macAddr1", "inMaint1"); + + LInterfaceInstance lInterfaceInstance2 = new LInterfaceInstance (); + lInterfaceInstance2.setInterfaceId("interfaceId1"); + lInterfaceInstance2.setInterfaceName("interfaceName1"); + lInterfaceInstance2.setInterfaceRole("interfaceRole1"); + lInterfaceInstance2.setIsPortMirrored("isPortMirrored1"); + lInterfaceInstance2.setAdminStatus("adminStatus1"); + lInterfaceInstance2.setNetworkName("networkName1"); + lInterfaceInstance2.setMacAddr("macAddr1"); + lInterfaceInstance2.setInMaint("inMaint1"); + + lInterfaceInstance1.toJson(); + lInterfaceInstance1.toString(); + assertEquals("interfaceName1", lInterfaceInstance2.getInterfaceName()); + assertTrue(lInterfaceInstance1.equals(lInterfaceInstance1)); + assertTrue(lInterfaceInstance1.equals(lInterfaceInstance2)); + } + +} diff --git a/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/test/RestServiceTest.java b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/test/RestServiceTest.java new file mode 100644 index 0000000..bc649fb --- /dev/null +++ b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/test/RestServiceTest.java @@ -0,0 +1,230 @@ +/* + * ============LICENSE_START=================================================== + * Copyright (c) 2018 Amdocs + * ============================================================================ + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * ============LICENSE_END===================================================== + */ +package org.onap.logging_analytics.pomba.pomba_aai_context_builder.test; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.okJson; +import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig; +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MultivaluedHashMap; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.onap.pomba.contextbuilder.aai.Application; +import org.onap.pomba.contextbuilder.aai.service.rs.RestService; +import org.onap.pomba.contextbuilder.aai.util.RestUtil; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.EnableAutoConfiguration; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.context.TestPropertySource; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.onap.pomba.common.datatypes.ModelContext; +import org.onap.pomba.common.datatypes.VFModule; +import org.onap.pomba.common.datatypes.VM; +import org.onap.pomba.common.datatypes.VNF; +import org.json.JSONObject; +import com.google.gson.Gson; +import com.github.tomakehurst.wiremock.junit.WireMockRule; + +@RunWith(SpringJUnit4ClassRunner.class) +@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class}) +@WebAppConfiguration +@SpringBootTest (classes = Application.class) +@TestPropertySource(properties = { "aai.serviceName=localhost", + "aai.servicePort=9806", "aai.httpProtocol=http", + "http.userId=admin", "http.password=OBF:1u2a1toa1w8v1tok1u30"}) +public class RestServiceTest { + @Autowired + private String aaiPathToSearchNodeQuery; + + @Autowired + private String httpBasicAuthorization; + + @Autowired + private RestService dummyRestSvc; + + private String testRestHeaders = "aai-context-builder"; + + HttpHeaders mockHttpHeaders = mock(HttpHeaders.class); + + private static final String DEPTH = "?depth=2"; + + @Rule + public WireMockRule aaiEnricherRule = new WireMockRule(wireMockConfig().port(9806)); + + private void addResponse(String path, String classpathResource, WireMockRule thisMock) throws IOException { + String payload = readFully(ClassLoader.getSystemResourceAsStream(classpathResource)); + thisMock.stubFor(get(path).willReturn(okJson(payload))); + } + + private String readFully(InputStream in) throws IOException { + char[] cbuf = new char[1024]; + StringBuilder content = new StringBuilder(); + try (InputStreamReader reader = new InputStreamReader(in, "UTF-8")) { + int count; + while ((count = reader.read(cbuf)) >= 0) { + content.append(cbuf, 0, count); + } + } + return content.toString(); + } + + private static MultivaluedMap buildHeaders( + String partnerName, String transactionId, String authorization) { + + MultivaluedMap headers = new MultivaluedHashMap<>(); + headers.put(RestUtil.FROM_APP_ID, Collections.singletonList(partnerName)); + headers.put(RestUtil.TRANSACTION_ID, Collections.singletonList(transactionId)); + if (null != authorization) { + headers.put(RestUtil.AUTHORIZATION, Collections.singletonList(authorization)); + } + return headers; + } + + ///Verify the relationship serviceInstanceId -> vnf -> vserver -> pserver + @Test + public void testGetContext_VSERVER_PSERVER() throws Exception { + + String transactionId = UUID.randomUUID().toString(); + String serviceInstanceId = "adc3cc2a-c73e-414f-8ddb-367de81300cb"; //match to the test data in junit/queryNodeData-1.json + String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId; + + // Test with No Partner Name + final MultivaluedMap multivaluedMapImpl = buildHeaders( + transactionId, testRestHeaders, httpBasicAuthorization); + + // 1. simulate the response to obtainResourceLink based on ServiceInstanceId + addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule); + // 2. simulate the response of AAI (1 vnf) + // note: match serviceInstanceId in (1) + addResponse( "/aai/v13/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb", + "junit/aai-service-instance_set2.json", aaiEnricherRule); + + // 3. simulate the rsp of VNF (with 1 vserver) + // note: match vnf_id in (2) + addResponse( "/aai/v13/network/generic-vnfs/generic-vnf/8a9ddb25-2e79-449c-a40d-5011bac0da39" + DEPTH, + "junit/genericVnfInput_set2.json", aaiEnricherRule); + + // 4. simulate the rsp of vserer + // note: match to vserver-id to the path of "vserver" in (3) + addResponse( + "/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant" + + "/b49b830686654191bb1e952a74b014ad/vservers/vserver/b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a", + "junit/aai-vserver.json", aaiEnricherRule); + + // 5. simulate the rsp of pserver + // note: match pserver hostname to the path of "pserver" in (4) + addResponse( + "/aai/v13/cloud-infrastructure/pservers/pserver/mtn96compute.cci.att.com" + DEPTH, + "junit/pserverInput_set2.json", aaiEnricherRule); + + when(mockHttpHeaders.getRequestHeaders()).thenReturn(multivaluedMapImpl); + + Response response = this.dummyRestSvc.getContext(mockHttpHeaders, httpBasicAuthorization, testRestHeaders, transactionId, + serviceInstanceId); + + assertEquals(Status.OK.getStatusCode(), response.getStatus()); + Gson gson = new Gson(); + ModelContext modelCtx = gson.fromJson((String) response.getEntity(), ModelContext.class); + // verify results + List vnfList = modelCtx.getVnfs(); + assertEquals(vnfList.size(), 1); + List vfModuleList = vnfList.get(0).getVfModules(); + assertEquals(vfModuleList.size(), 1); + List vmList = vfModuleList.get(0).getVms(); + assertEquals(vmList.size(), 1); + assertEquals(vmList.get(0).getUuid(), "b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a"); //vserver-id + assertEquals(vmList.get(0).getPServer().getName(), "mtn96compute.cci.att.com"); //pserver-name + + } + + ///Verify the relationship serviceInstanceId -> vnf -> vserver -> LInterfaceList + @Test + public void testGetContext_VSERVER_L_interface_List() throws Exception { + + String transactionId = UUID.randomUUID().toString(); + String serviceInstanceId = "adc3cc2a-c73e-414f-8ddb-367de81300cb"; //match to the test data in junit/queryNodeData-1.json + String queryNodeUrl = aaiPathToSearchNodeQuery + serviceInstanceId; + + // Test with No Partner Name + final MultivaluedMap multivaluedMapImpl = buildHeaders( + transactionId, testRestHeaders, httpBasicAuthorization); + + // 1. simulate the response to obtainResourceLink based on ServiceInstanceId + addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule); + // 2. simulate the response of AAI (1 vnf) + // note: match serviceInstanceId in (1) + addResponse( "/aai/v13/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb", + "junit/aai-service-instance_set2.json", aaiEnricherRule); + + // 3. simulate the rsp of VNF (with 1 vserver) + // note: match vnf_id in (2) + addResponse( "/aai/v13/network/generic-vnfs/generic-vnf/8a9ddb25-2e79-449c-a40d-5011bac0da39" + DEPTH, + "junit/genericVnfInput_set2.json", aaiEnricherRule); + + // 4. simulate the rsp of vserer + // note: match to vserver-id to the path of "vserver" in (3) + addResponse( + "/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/tenants/tenant" + + "/b49b830686654191bb1e952a74b014ad/vservers/vserver/b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a", + "junit/aai-vserver-set3.json", aaiEnricherRule); + + // 5. simulate the rsp of LInterface + // note: match l-Interface hostname to the path of "l-interface" in (4) + addResponse( + "/aai/v13/l-interfaces/l-interface/junit-l-interface-name1" + DEPTH, + "junit/l-interface-input.json", aaiEnricherRule); + addResponse( + "/aai/v13/l-interfaces/l-interface/junit-l-interface-name2" + DEPTH, + "junit/l-interface-input2.json", aaiEnricherRule); + + when(mockHttpHeaders.getRequestHeaders()).thenReturn(multivaluedMapImpl); + + Response response = this.dummyRestSvc.getContext(mockHttpHeaders, httpBasicAuthorization, testRestHeaders, transactionId, + serviceInstanceId); + + assertEquals(Status.OK.getStatusCode(), response.getStatus()); + Gson gson = new Gson(); + ModelContext modelCtx = gson.fromJson((String) response.getEntity(), ModelContext.class); + // verify results + List vnfList = modelCtx.getVnfs(); + assertEquals(vnfList.size(), 1); + List vfModuleList = vnfList.get(0).getVfModules(); + assertEquals(vfModuleList.size(), 1); + List vmList = vfModuleList.get(0).getVms(); + assertEquals(vmList.size(), 1); + assertEquals(vmList.get(0).getUuid(), "b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a"); //vserver-id + assertEquals(vmList.get(0).getLInterfaceList().size(), 2); + assertEquals(vmList.get(0).getLInterfaceList().get(0).getName(), "junit-l-interface-name1"); //l-interface-name + assertEquals(vmList.get(0).getLInterfaceList().get(1).getName(), "junit-l-interface-name2"); //l-interface-name + } +} diff --git a/src/test/resources/junit/aai-vserver-set3.json b/src/test/resources/junit/aai-vserver-set3.json new file mode 100644 index 0000000..f50d65a --- /dev/null +++ b/src/test/resources/junit/aai-vserver-set3.json @@ -0,0 +1,110 @@ +{ + "vserver-id": "b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a", + "vserver-name": "Firewall-0", + "vserver-name2": "Firewall-0", + "prov-status": "ACTIVE", + "vserver-selflink": "http://10.12.25.2:8774/v2.1/b49b830686654191bb1e952a74b014ad/servers/b494cd6e-b9f3-45e0-afe7-e1d1a5f5d74a", + "in-maint": false, + "is-closed-loop-disabled": false, + "resource-version": "1528481820321", + "relationship-list": { + "relationship": [ + { + "related-to": "l-interface", + "relationship-label": "tosca.relationships.HostedOn", + "related-link": "/aai/v13/l-interfaces/l-interface/junit-l-interface-name1", + "relationship-data": [ + { + "relationship-key": "l-interface.interface-name", + "relationship-value": "junit-l-interface-name1" + } + ], + "related-to-property": [ + { "property-key": "l-interface.interface-id", + "property-value": "junit-l-interface-1" + } + ] + }, + { + "related-to": "l-interface", + "relationship-label": "tosca.relationships.HostedOn", + "related-link": "/aai/v13/l-interfaces/l-interface/junit-l-interface-name2", + "relationship-data": [ + { + "relationship-key": "l-interface.interface-name", + "relationship-value": "junit-l-interface-name2" + } + ], + "related-to-property": [ + { "property-key": "l-interface.interface-id", + "property-value": "junit-l-interface-2" + } + ] + }, + { + "related-to": "generic-vnf", + "related-link": "/aai/v13/network/generic-vnfs/generic-vnf/8a9ddb25-2e79-449c-a40d-5011bac0da39", + "relationship-data": [ + { + "relationship-key": "generic-vnf.vnf-id", + "relationship-value": "8a9ddb25-2e79-449c-a40d-5011bac0da39" + } + ], + "related-to-property": [ + { + "property-key": "generic-vnf.vnf-name", + "property-value": "Firewall-1" + } + ] + }, + { + "related-to": "flavor", + "related-link": "/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/flavors/flavor/764efb04-5a46-4806-a766-2bdd24559f39", + "relationship-data": [ + { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "CloudOwner" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "RegionOne" + }, + { + "relationship-key": "flavor.flavor-id", + "relationship-value": "764efb04-5a46-4806-a766-2bdd24559f39" + } + ], + "related-to-property": [ + { + "property-key": "flavor.flavor-name", + "property-value": "m1.medium" + } + ] + }, + { + "related-to": "image", + "related-link": "/aai/v13/cloud-infrastructure/cloud-regions/cloud-region/CloudOwner/RegionOne/images/image/42fd42f8-cf81-4f4c-a552-d4b124f83b0b", + "relationship-data": [ + { + "relationship-key": "cloud-region.cloud-owner", + "relationship-value": "CloudOwner" + }, + { + "relationship-key": "cloud-region.cloud-region-id", + "relationship-value": "RegionOne" + }, + { + "relationship-key": "image.image-id", + "relationship-value": "42fd42f8-cf81-4f4c-a552-d4b124f83b0b" + } + ], + "related-to-property": [ + { + "property-key": "image.image-name", + "property-value": "unknown" + } + ] + } + ] + } +} diff --git a/src/test/resources/junit/l-interface-input.json b/src/test/resources/junit/l-interface-input.json new file mode 100644 index 0000000..0f80367 --- /dev/null +++ b/src/test/resources/junit/l-interface-input.json @@ -0,0 +1,10 @@ +{ + "interface-id": "junit-l-interface-1", + "interface-name": "junit-l-interface-name1", + "interface-role": "interface-role1", + "is-port-mirrored": "true", + "admin-status": "admin-status1", + "network-name": "network-name-amdocs", + "macaddr": "macaddr-1", + "in-maint": "true" +} \ No newline at end of file diff --git a/src/test/resources/junit/l-interface-input2.json b/src/test/resources/junit/l-interface-input2.json new file mode 100644 index 0000000..3bcbbda --- /dev/null +++ b/src/test/resources/junit/l-interface-input2.json @@ -0,0 +1,10 @@ +{ + "interface-id": "junit-l-interface-2", + "interface-name": "junit-l-interface-name2", + "interface-role": "interface-role2", + "is-port-mirrored": "true", + "admin-status": "admin-status2", + "network-name": "network-name-amdocs", + "macaddr": "macaddr-2", + "in-maint": "true" +} \ No newline at end of file -- cgit 1.2.3-korg