aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhillip Leigh <phillip.leigh@amdocs.com>2018-09-04 11:28:49 -0400
committerPhillip Leigh <phillip.leigh@amdocs.com>2018-09-05 15:34:37 -0400
commit797bf1d50236fddcbbb2ca091729e2e64b047f73 (patch)
treeaad1b35fea66f18b71bf2b975d50883a927ac2fd
parentae69dc13d976b67c0278890b852444a134e23ca9 (diff)
Obtain resouce-link based on service-instance
Issue-ID: LOG-461 Change-Id: Ieb3fb761be2237808ab9d709b3fadc7e241963de Signed-off-by: Phillip Leigh <phillip.leigh@amdocs.com>
-rw-r--r--config/application.properties2
-rw-r--r--pom.xml6
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java8
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java4
-rw-r--r--src/main/java/org/onap/pomba/contextbuilder/aai/util/RestUtil.java68
-rw-r--r--src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/RestUtilTest.java82
-rw-r--r--src/test/resources/junit/queryNodeData-1.json8
-rw-r--r--src/test/resources/junit/queryNodeData-nullResourceLink.json8
8 files changed, 182 insertions, 4 deletions
diff --git a/config/application.properties b/config/application.properties
index a3cc78b..4ce5de9 100644
--- a/config/application.properties
+++ b/config/application.properties
@@ -41,5 +41,7 @@ http.password=OBF:1u2a1toa1w8v1tok1u30
# {0} = customerId {1} = serviceType {2} = serviceInstanceId
aai.serviceInstancePath=/aai/v11/business/customers/customer/{0}/service-subscriptions/service-subscription/{1}/service-instances/service-instance/{2}
+aai.searchNodeQuery=/aai/v11/search/nodes-query?search-node-type=service-instance&filter=service-instance-id:EQUALS:
+
#Servlet context parameters
server.context_parameters.p-name=value #context parameter with p-name as key and value as value.
diff --git a/pom.xml b/pom.xml
index 061e528..bab6e32 100644
--- a/pom.xml
+++ b/pom.xml
@@ -148,6 +148,12 @@
<version>1.10.19</version>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>com.github.tomakehurst</groupId>
+ <artifactId>wiremock</artifactId>
+ <version>2.18.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java b/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java
index 9c6d11d..7befdc9 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/aai/AAIConfiguration.java
@@ -104,4 +104,12 @@ public class AAIConfiguration {
return serviceInstancePath;
}
+ @Value("${aai.searchNodeQuery}")
+ private String searchNodeQuery;
+
+ @Bean(name="aaiPathToSearchNodeQuery")
+ public String getAaiPathToSearchNodeQuery() {
+ return searchNodeQuery.trim();
+ }
+
}
diff --git a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java
index ff09e55..2ec49f3 100644
--- a/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java
+++ b/src/main/java/org/onap/pomba/contextbuilder/aai/service/SpringServiceImpl.java
@@ -39,6 +39,8 @@ public class SpringServiceImpl implements SpringService {
private String aaiServiceInstancePath;
@Autowired
private String aaiBasicAuthorization;
+ @Autowired
+ private String aaiPathToSearchNodeQuery;
public SpringServiceImpl() {
// needed for instantiation
@@ -55,7 +57,7 @@ public class SpringServiceImpl implements SpringService {
// Retrieve the service instance information from AAI
try {
- context= RestUtil.retrieveAAIModelData(aaiClient, aaiBaseUrl, aaiServiceInstancePath, tranId, serviceInstanceId, modelVersionId, modelInvariantId, serviceType, customerId,aaiBasicAuthorization);
+ context= RestUtil.retrieveAAIModelData(aaiClient, aaiBaseUrl, aaiPathToSearchNodeQuery, aaiServiceInstancePath, tranId, serviceInstanceId, modelVersionId, modelInvariantId, serviceType, customerId,aaiBasicAuthorization);
} catch (AuditException ae) {
throw ae;
} catch (Exception e) {
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 da7d241..905a8bc 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
@@ -31,6 +31,7 @@ import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response.Status;
import org.json.JSONArray;
+import org.json.JSONException;
import org.json.JSONObject;
import org.onap.aai.restclient.client.OperationResult;
import org.onap.aai.restclient.client.RestClient;
@@ -48,7 +49,7 @@ import org.onap.pomba.contextbuilder.aai.exception.AuditError;
import org.onap.pomba.contextbuilder.aai.exception.AuditException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
+import org.springframework.beans.factory.annotation.Autowired;
public class RestUtil {
@@ -72,12 +73,17 @@ public class RestUtil {
// Service Catalog
private static final String CATALOG_GENERIC_VNF = "generic-vnf";
private static final String CATALOG_VNFC = "vnfc";
+ private static final String CATALOG_SERVICE_INSTANCE = "service-instance";
+
// Relationship Json Path
private static final String RELATIONSHIP_LIST = "relationship-list";
private static final String RELATIONSHIP = "relationship";
+ private static final String RESULT_DATA = "result-data";
private static final String JSON_ATT_RELATED_TO = "related-to";
private static final String JSON_ATT_RELATED_LINK = "related-link";
+ private static final String JSON_ATT_RESOURCE_TYPE = "resource-type";
+ private static final String JSON_ATT_RESOURCE_LINK = "resource-link";
private static final String EMPTY_JSON_STRING = "{}";
private static final String DELIMITER = "$";
@@ -105,6 +111,7 @@ public class RestUtil {
throw new AuditException(AuditError.INVALID_REQUEST_URL_MISSING_PARAMETER + MODEL_INVARIANT_ID,
Status.BAD_REQUEST);
}
+
// serviceType
if (serviceType == null || serviceType.isEmpty()) {
throw new AuditException(AuditError.INVALID_REQUEST_URL_MISSING_PARAMETER + SERVICE_TYPE, Status.BAD_REQUEST);
@@ -161,7 +168,7 @@ public class RestUtil {
/*
* Trigger external API call to AAI to retrieve Service Instance data (i.e. genericVNF and VNFC)
*/
- public static ModelContext retrieveAAIModelData(RestClient aaiClient, String baseURL, String aaiServiceInstancePath,
+ public static ModelContext retrieveAAIModelData(RestClient aaiClient, String baseURL, String aaiPathToSearchNodeQuery, String aaiServiceInstancePath,
String transactionId, String serviceInstanceId, String modelVersionId, String modelInvariantId,
String serviceType, String customerId, String aaiBasicAuthorization) throws AuditException {
String serviceInstancePayload = null;
@@ -173,6 +180,8 @@ public class RestUtil {
Map<String, List<VnfcInstance>> vnfMap = new HashMap<String, List<VnfcInstance>>(); // MAP the vnf-id as the
// key, and list of the vNFC
// pojo object
+ // Obtain resource-link based on resource-type = service-Instance
+ String resourceLink = obtainResouceLinkBasedOnServiceInstanceFromAAI(aaiClient, baseURL, aaiPathToSearchNodeQuery, serviceInstanceId, transactionId, aaiBasicAuthorization);
String url = baseURL
+ generateServiceInstanceURL(aaiServiceInstancePath, customerId, serviceType, serviceInstanceId);
@@ -442,5 +451,60 @@ public class RestUtil {
return MessageFormat.format(siPath, customerId, serviceType, serviceInstanceId);
}
+ public static String obtainResouceLinkBasedOnServiceInstanceFromAAI(RestClient aaiClient, String baseURL, String aaiPathToSearchNodeQuery, String serviceInstanceId,
+ String transactionId, String aaiBasicAuthorization) throws AuditException {
+
+ String url = generateGetCustomerInfoUrl(baseURL, aaiPathToSearchNodeQuery, serviceInstanceId);
+ String customerInfoString = getResource(aaiClient, url, aaiBasicAuthorization, transactionId, MediaType.valueOf(MediaType.APPLICATION_JSON));
+
+ // Handle the case if the service instance is not found in AAI
+ if (isEmptyJson(customerInfoString)) {
+ log.info(LogMessages.NOT_FOUND, "Service Instance" , serviceInstanceId);
+ // Only return the empty Json on the root level. i.e service instance
+ return null;
+ }
+
+ return extractResourceLinkBasedOnResourceType(customerInfoString, CATALOG_SERVICE_INSTANCE);
+ }
+
+ private static String generateGetCustomerInfoUrl (String baseURL, String aaiPathToSearchNodeQuery ,String serviceInstanceId) {
+ return baseURL + aaiPathToSearchNodeQuery + serviceInstanceId;
+ }
+
+ /*
+ * Extract the resource-Link from Json payload. For example
+ * {
+ * "result-data": [
+ * {
+ * "resource-type": "service-instance",
+ * "resource-link": "/aai/v11/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb"
+ * }
+ * ]
+ * }
+ */
+ private static String extractResourceLinkBasedOnResourceType(String payload, String catalog) throws AuditException {
+ String resourceLink = null;
+ log.info("Fetching the resource-link based on resource-type=" + catalog);
+
+ try {
+ JSONArray result_data_list = new JSONObject(payload).getJSONArray(RESULT_DATA);
+ if (result_data_list != null) {
+ for (int i = 0; i < result_data_list.length(); i++) {
+ JSONObject obj = result_data_list.optJSONObject(i);
+ if (obj.has(JSON_ATT_RESOURCE_TYPE) && (obj.getString(JSON_ATT_RESOURCE_TYPE).equals(catalog) )) {
+ resourceLink = obj.getString(JSON_ATT_RESOURCE_LINK);
+ log.info(resourceLink);
+ return resourceLink;
+ }
+ }
+ }
+ } catch (JSONException e) {
+ log.error(e.getMessage());
+ throw new AuditException(AuditError.JSON_READER_PARSE_ERROR + " " + e.getMessage());
+ }
+
+ log.warn("resource-link CANNOT be found: ", payload );
+ return resourceLink;
+ }
}
diff --git a/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/RestUtilTest.java b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/RestUtilTest.java
index 9757a2c..f8991c1 100644
--- a/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/RestUtilTest.java
+++ b/src/test/java/org/onap/logging_analytics/pomba/pomba_aai_context_builder/RestUtilTest.java
@@ -17,13 +17,49 @@
*/
package org.onap.logging_analytics.pomba.pomba_aai_context_builder;
+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.junit.Assert.assertTrue;
-
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.UUID;
+import org.junit.Rule;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.pomba.contextbuilder.aai.Application;
import org.onap.pomba.contextbuilder.aai.exception.AuditException;
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 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=9808", "aai.httpProtocol=http" })
public class RestUtilTest {
+ @Autowired
+ private RestClient aaiClient;
+ @Autowired
+ private String aaiBaseUrl;
+ @Autowired
+ private String aaiPathToSearchNodeQuery;
+ @Autowired
+ private String aaiBasicAuthorization;
+
+ @Rule
+ public WireMockRule aaiEnricherRule = new WireMockRule(wireMockConfig().port(9808));
@Test
public void testValidateURL() {
@@ -99,4 +135,48 @@ public class RestUtilTest {
assertTrue(RestUtil.isEmptyJson("{}"));
assertTrue(!RestUtil.isEmptyJson("{Not Empty}"));
}
+
+ @Test
+ public void testObtainResouceLinkBasedOnServiceInstanceFromAAI() 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;
+ addResponse(queryNodeUrl, "junit/queryNodeData-1.json", aaiEnricherRule);
+
+ String resourceLinkUlr = RestUtil.obtainResouceLinkBasedOnServiceInstanceFromAAI(aaiClient, aaiBaseUrl, aaiPathToSearchNodeQuery, serviceInstanceId, transactionId, aaiBasicAuthorization);
+
+ String returnedInstanceId = resourceLinkUlr.substring(resourceLinkUlr.lastIndexOf("/")+1).trim();
+ assertEquals(serviceInstanceId, returnedInstanceId);
+ }
+
+ @Test
+ public void testObtainResouceLinkBasedOnServiceInstanceFromAAI_nullResourceLink() 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;
+ addResponse(queryNodeUrl, "junit/queryNodeData-nullResourceLink.json", aaiEnricherRule);
+
+ try {
+ RestUtil.obtainResouceLinkBasedOnServiceInstanceFromAAI(aaiClient, aaiBaseUrl, aaiPathToSearchNodeQuery, serviceInstanceId, transactionId, aaiBasicAuthorization);
+ } catch (AuditException e) {
+ assertTrue(e.getMessage().contains("JSONObject[\"resource-link\"] not found"));
+ }
+ }
+
+ 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();
+ }
}
diff --git a/src/test/resources/junit/queryNodeData-1.json b/src/test/resources/junit/queryNodeData-1.json
new file mode 100644
index 0000000..501830b
--- /dev/null
+++ b/src/test/resources/junit/queryNodeData-1.json
@@ -0,0 +1,8 @@
+{
+ "result-data": [
+ {
+ "resource-type": "service-instance",
+ "resource-link": "/aai/v11/business/customers/customer/DemoCust_651800ed-2a3c-45f5-b920-85c1ed155fc2/service-subscriptions/service-subscription/vFW/service-instances/service-instance/adc3cc2a-c73e-414f-8ddb-367de81300cb"
+ }
+ ]
+}
diff --git a/src/test/resources/junit/queryNodeData-nullResourceLink.json b/src/test/resources/junit/queryNodeData-nullResourceLink.json
new file mode 100644
index 0000000..36eb667
--- /dev/null
+++ b/src/test/resources/junit/queryNodeData-nullResourceLink.json
@@ -0,0 +1,8 @@
+{
+ "result-data": [
+ {
+ "resource-type": "service-instance",
+ "related-link": "/aai/v11/network/vnfcs/vnfc/zrdm5aepdg01vmg003"
+ }
+ ]
+}