summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNorm Traxler <normant@amdocs.com>2018-11-27 22:18:16 +0000
committerNorm Traxler <norman.traxler@amdocs.com>2018-11-28 14:24:42 -0500
commit9a0c9790a1dc31dcc2db199b6f0ff76e796c2597 (patch)
tree836a34fb2e4a8d1dd78cc9ed18553278c5a2ca1f
parent2f93fe9cf3c05d6606e37576121801dbdb98dd68 (diff)
ND get VM info from Openstack
Issue-ID: SDNC-533 Change-Id: If50c4ae02349824a4e179e30ea1ee29d3afe6ab2 Signed-off-by: Norm Traxler <normant@amdocs.com>
-rw-r--r--pomba/network-discovery/config/application.properties27
-rw-r--r--pomba/network-discovery/config/auth/client-cert-onap.p12bin0 -> 2556 bytes
-rw-r--r--pomba/network-discovery/config/auth/osauth.json18
-rw-r--r--pomba/network-discovery/config/jolt/l3-network.json25
-rw-r--r--pomba/network-discovery/config/jolt/vserver.json32
-rw-r--r--pomba/network-discovery/pom.xml18
-rw-r--r--pomba/network-discovery/src/main/docker/Dockerfile3
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/Application.java2
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/ApplicationException.java19
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/OpenstackConfiguration.java (renamed from pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/EnricherConfiguration.java)72
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/OSAuthentication.java78
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/SpringServiceImpl.java206
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/rs/RestServiceImpl.java11
-rw-r--r--pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/util/TransformationUtil.java99
-rw-r--r--pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/NetworkDiscoveryTest.java169
-rw-r--r--pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/TestHttpServletRequest.java500
-rw-r--r--pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/util/TransformationUtilTest.java136
-rw-r--r--pomba/network-discovery/src/test/resources/jolt/l3network-expected.json14
-rw-r--r--pomba/network-discovery/src/test/resources/jolt/l3network-input.json32
-rw-r--r--pomba/network-discovery/src/test/resources/jolt/vserver-expected.json15
-rw-r--r--pomba/network-discovery/src/test/resources/jolt/vserver-input.json92
21 files changed, 836 insertions, 732 deletions
diff --git a/pomba/network-discovery/config/application.properties b/pomba/network-discovery/config/application.properties
index 6dba59d..f6a889e 100644
--- a/pomba/network-discovery/config/application.properties
+++ b/pomba/network-discovery/config/application.properties
@@ -22,20 +22,13 @@ server.context_parameters.p-name=value #context parameter with p-name as key and
basicAuth.username=admin
basicAuth.password=OBF:1u2a1toa1w8v1tok1u30
-enricher.types = vserver, l3-network
-enricher.type.vserver.url = /enricher/v11/cloud-infrastructure/vservers/vserver/{0}?sot=!aai
-enricher.type.l3-network.url = /enricher/v11/network/l3-networks/l3-network/{0}?sot=!aai
-
-# Mapping from Enricher Attribute name to POMBA Attribute name in the format
-# <Enricher Attribute Name>:<Pomba Attribute Name>; and separated by semicolon ";"
-# for example,
-# vserser-id:id;
-# means Attribute name "vserer-id" from Enricher will be converted to "id" in POMBA.
-enricher.attributeNameMappingList=Id:id;id:id;vserver-id:id;name:name;locked:inMaintenance; \
- hostname:hostName;status:status;vm_state:vmState;vm-state:vmState;admin_state_up:adminState; \
- favor.disk:flavorDisk;flavor.ephemeral:flavorEphemoral;flavor.extra_specs.hw.cpu_model:flavorHwCpuModel; \
- flavor.extra_specs.hw.cpu_policy:flavorHwCpuPolicy;flavor.extra_specs.hw.mem_page_size:flavorHwMemPageSize; \
- flavor.original_name:flavorOriginalName;flavor.ram:flavorRam;flavor.swap:flavorSwag;flavorvcpus:flavorVcpus; \
- image.id:imageId;hostId:hostId;host:host;host_status:hostStatus;security_group.name:securityGroupName; \
- serverName:serverName;metadata.myservername:otherServerName;shared:sharedNetwork;subnets:subnets; \
- userId:userId;tenant_id:tenantId \ No newline at end of file
+openstack.identity.url = http://10.69.36.11:5000/v3/auth/tokens
+openstack.identity.user = ralph
+openstack.identity.password = OBF:1w951ugg1vun1uha1w8l
+
+openstack.types = vserver, l3-network
+openstack.type.vserver.url = http://10.69.36.11:8774/v2.1/servers/{0}
+openstack.type.l3-network.url = http://10.69.36.11:9696/v2.0/networks/{0}
+
+openstack.api.microversion = 2.42
+
diff --git a/pomba/network-discovery/config/auth/client-cert-onap.p12 b/pomba/network-discovery/config/auth/client-cert-onap.p12
new file mode 100644
index 0000000..dbf4fca
--- /dev/null
+++ b/pomba/network-discovery/config/auth/client-cert-onap.p12
Binary files differ
diff --git a/pomba/network-discovery/config/auth/osauth.json b/pomba/network-discovery/config/auth/osauth.json
new file mode 100644
index 0000000..95dec53
--- /dev/null
+++ b/pomba/network-discovery/config/auth/osauth.json
@@ -0,0 +1,18 @@
+{
+ "auth": {
+ "identity": {
+ "methods": [
+ "password"
+ ],
+ "password": {
+ "user": {
+ "name": "%USER%",
+ "domain": {
+ "name": "Default"
+ },
+ "password": "%PASSWORD%"
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/pomba/network-discovery/config/jolt/l3-network.json b/pomba/network-discovery/config/jolt/l3-network.json
new file mode 100644
index 0000000..0afe4a2
--- /dev/null
+++ b/pomba/network-discovery/config/jolt/l3-network.json
@@ -0,0 +1,25 @@
+[
+ {
+ "operation": "shift",
+ "spec": {
+ "network": {
+ "id": "l3-network.id",
+ "name": "l3-network.name",
+ "admin_state_up": "l3-network.AdminState",
+ "shared": "l3-network.sharedNetwork",
+ "status": "l3-network.status",
+ "subnets": "l3-network.subnets",
+ "tenant_id": "l3-network.tenantId"
+ }
+ }
+ },
+ {
+ "operation": "default",
+ "spec": {
+ "*": {
+ "host-status": "UNKNOWN"
+ }
+ }
+ }
+
+]
diff --git a/pomba/network-discovery/config/jolt/vserver.json b/pomba/network-discovery/config/jolt/vserver.json
new file mode 100644
index 0000000..cc9e26d
--- /dev/null
+++ b/pomba/network-discovery/config/jolt/vserver.json
@@ -0,0 +1,32 @@
+[
+ {
+ "operation": "shift",
+ "spec": {
+ "server": {
+ "id": "vserver.id",
+ "name": "vserver.name",
+ "locked": "vserver.inMaintenance",
+ "OS-EXT-SRV-ATTR:hostname": "vserver.hostname",
+ "image": {
+ "id": "vserver.imageId"
+ },
+
+ "status": "vserver.status",
+ "OS-EXT-STS:vm_state": "vserver.vmState",
+ "tenant_id": "vserver.tenantId",
+ "hostId": "vserver.hostId",
+ "OS-EXT-SRV-ATTR:host": "vserver.host",
+ "host_status": "vserver.hostStatus"
+ }
+ }
+ },
+ {
+ "operation": "default",
+ "spec": {
+ "*": {
+ "hostStatus": "UNKNOWN"
+ }
+ }
+ }
+
+]
diff --git a/pomba/network-discovery/pom.xml b/pomba/network-discovery/pom.xml
index 24aa3de..18a8587 100644
--- a/pomba/network-discovery/pom.xml
+++ b/pomba/network-discovery/pom.xml
@@ -50,6 +50,23 @@ limitations under the License.
</dependencyManagement>
<dependencies>
+ <!-- Jolt transformation dependencies -->
+ <dependency>
+ <groupId>com.bazaarvoice.jolt</groupId>
+ <artifactId>jolt-core</artifactId>
+ <version>0.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>com.bazaarvoice.jolt</groupId>
+ <artifactId>json-utils</artifactId>
+ <version>0.1.0</version>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.5</version>
+ </dependency>
+
<!-- Springframework dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -279,6 +296,7 @@ limitations under the License.
<includes>
<include>*.properties</include>
<include>*.xml</include>
+ <include>**/*.json</include>
</includes>
<filtering>false</filtering>
</resource>
diff --git a/pomba/network-discovery/src/main/docker/Dockerfile b/pomba/network-discovery/src/main/docker/Dockerfile
index e9be214..45a8c5a 100644
--- a/pomba/network-discovery/src/main/docker/Dockerfile
+++ b/pomba/network-discovery/src/main/docker/Dockerfile
@@ -6,6 +6,7 @@ ARG MICROSERVICE_HOME=/opt/app/
RUN mkdir -p $MICROSERVICE_HOME
RUN mkdir -p $MICROSERVICE_HOME/config/
RUN mkdir -p $MICROSERVICE_HOME/config/auth/
+RUN mkdir -p $MICROSERVICE_HOME/config/jolt/
RUN mkdir -p $MICROSERVICE_HOME/lib/
RUN mkdir -p $MICROSERVICE_HOME/bin/
@@ -17,4 +18,4 @@ RUN chmod 755 $MICROSERVICE_HOME/config/*
RUN chmod 755 $MICROSERVICE_HOME/lib/*
RUN chmod 755 $MICROSERVICE_HOME/bin/*
-CMD ["/opt/app/bin/startService.sh"] \ No newline at end of file
+CMD ["/opt/app/bin/startService.sh"]
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/Application.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/Application.java
index c976678..e7e2208 100644
--- a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/Application.java
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/Application.java
@@ -38,7 +38,7 @@ public class Application extends SpringBootServletInitializer {
return application.sources(Application.class);
}
- public static void main(String[] args) throws Exception {
+ public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
} \ No newline at end of file
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/ApplicationException.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/ApplicationException.java
index fa29645..98bb2e7 100644
--- a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/ApplicationException.java
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/ApplicationException.java
@@ -45,11 +45,7 @@ public class ApplicationException extends Exception {
private static final long serialVersionUID = -4874149714911165454L;
private final Status httpStatus;
- private String responseCode;
-
- public ApplicationException(String message) {
- this(message, Status.INTERNAL_SERVER_ERROR);
- }
+ private final String responseCode;
public ApplicationException(Error errorCode, Status httpStatus, Object... args) {
super(errorCode.getMessage(args));
@@ -61,19 +57,6 @@ public class ApplicationException extends Exception {
this.httpStatus = httpStatus;
}
- public ApplicationException(String message, Status httpStatus) {
- super(message);
- if (httpStatus == null) {
- throw new NullPointerException("httpStatus");
- }
- this.httpStatus = httpStatus;
- }
-
- public ApplicationException(String message, Exception cause) {
- super(message, cause);
- this.httpStatus = Status.INTERNAL_SERVER_ERROR;
- }
-
public Status getHttpStatus() {
return this.httpStatus;
}
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/EnricherConfiguration.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/OpenstackConfiguration.java
index 62ea3f7..ee18397 100644
--- a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/EnricherConfiguration.java
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/OpenstackConfiguration.java
@@ -20,58 +20,77 @@ package org.onap.sdnc.apps.pomba.networkdiscovery;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
+
+import org.eclipse.jetty.util.security.Password;
import org.onap.aai.restclient.client.RestClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
-import com.google.common.base.Splitter;
@Configuration
-public class EnricherConfiguration {
+public class OpenstackConfiguration {
@Autowired
private Environment env;
- @Value("${enricher.url:https://localhost:9505}")
- private String url;
+ @Value("${openstack.identity.url:http://localhost:5000/v3}")
+ private String identityUrl;
+
+ @Value("${openstack.identity.user}")
+ private String identityUser;
+
+ @Value("${openstack.identity.password}")
+ private String identityPassword;
- @Value("${enricher.keyStorePath:config/auth/client-cert-onap.p12}")
+ @Value("${openstack.api.microversion}")
+ private String apiMicroversion;
+
+ @Value("${openstack.identity.keyStorePath:config/auth/client-cert-onap.p12}")
private String keyStorePath;
- @Value("${enricher.keyStorePassword:OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10}")
+ @Value("${openstack.identity.keyStorePassword:OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10}")
private String keyStorePassword;
- @Value("${enricher.connectionTimeout:5000}")
+ @Value("${openstack.connectionTimeout:5000}")
private int connectionTimeout;
- @Value("${enricher.readTimeout:60000}")
+ @Value("${openstack.readTimeout:60000}")
private int readTimeout;
- @Value("${enricher.attributeNameMappingList}")
- private String enricherAttributeNameMappingList;
-
- @Bean(name = "enricherClient")
+ @Bean(name = "openstackClient")
public RestClient restClient() {
return new RestClient().validateServerHostname(false)
.validateServerCertChain(false)
.connectTimeoutMs(this.connectionTimeout)
- .readTimeoutMs(this.readTimeout)
- .clientCertFile(this.keyStorePath)
- .clientCertPassword(org.eclipse.jetty.util.security.Password.deobfuscate(
- this.keyStorePassword));
+ .readTimeoutMs(this.readTimeout);
+ }
+
+ @Bean(name = "openstackIdentityUrl")
+ public String getIdentityURL() {
+ return this.identityUrl;
+ }
+
+ @Bean(name = "openstackIdentityUser")
+ public String getIdentityUser() {
+ return this.identityUser;
}
- @Bean(name = "enricherBaseUrl")
- public String getURL() {
- return this.url;
+ @Bean(name = "openstackIdentityPassword")
+ public String getIdentityPassword() {
+ return Password.deobfuscate(this.identityPassword);
}
- @Bean(name = "enricherTypeURLs")
- public Map<String, String> enricherTypeURLs() {
+ @Bean(name = "openstackApiMicroversion")
+ public String getApiMicroversion() {
+ return this.apiMicroversion;
+ }
+
+ @Bean(name = "openstackTypeURLs")
+ public Map<String, String> getOpenstackTypeURLs() {
Map<String, String> result = new HashMap<>();
- String types = this.env.getProperty("enricher.types");
+ String types = this.env.getProperty("openstack.types");
if (types == null) {
return result;
}
@@ -79,16 +98,11 @@ public class EnricherConfiguration {
StringTokenizer tokenizer = new StringTokenizer(types, ", ");
while (tokenizer.hasMoreTokens()) {
String type = tokenizer.nextToken();
- String enricherUrl = this.env.getProperty("enricher.type." + type + ".url");
- result.put(type, enricherUrl);
+ String openstackUrl = this.env.getProperty("openstack.type." + type + ".url");
+ result.put(type, openstackUrl);
}
return result;
}
- @Bean(name = "enricherAttributeNameMapping")
- public Map<String, String> getAttributeNameMap() {
- String noWhiteSpaceString = enricherAttributeNameMappingList.replaceAll("\\s", "");
- return (Splitter.on(";").withKeyValueSeparator(":").split(noWhiteSpaceString));
- }
}
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/OSAuthentication.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/OSAuthentication.java
new file mode 100644
index 0000000..fed52a0
--- /dev/null
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/OSAuthentication.java
@@ -0,0 +1,78 @@
+/*
+ * ============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.sdnc.apps.pomba.networkdiscovery.service;
+
+import static org.onap.sdnc.apps.pomba.networkdiscovery.ApplicationException.Error.UNAUTHORIZED;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedHashMap;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.commons.io.IOUtils;
+import org.onap.aai.restclient.client.OperationResult;
+import org.onap.aai.restclient.client.RestClient;
+import org.onap.logging.ref.slf4j.ONAPLogAdapter;
+import org.onap.sdnc.apps.pomba.networkdiscovery.ApplicationException;
+
+public class OSAuthentication {
+
+ private static final String CONFIG_AUTH_DIR = "config/auth";
+ private static final String X_SUBJECT_TOKEN = "X-Subject-Token";
+
+ private static final String USER_PATTERN = "%USER%";
+ private static final String PASSWORD_PATTERN = "%PASSWORD%";
+
+ private OSAuthentication() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ public static String getToken(String openstackIdentityUrl, String userId, String password, RestClient openstackClient, ONAPLogAdapter adapter)
+ throws IOException, ApplicationException {
+
+ MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
+
+ String mappingConfigPath = CONFIG_AUTH_DIR + File.separator + "osauth.json";
+
+ File file = new File(mappingConfigPath);
+ String payload = IOUtils.toString(new FileInputStream(file), "UTF-8");
+ payload = payload.replaceAll(USER_PATTERN, userId);
+ payload = payload.replaceAll(PASSWORD_PATTERN, password);
+
+ OperationResult result = openstackClient.post(openstackIdentityUrl, payload, headers,
+ MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);
+
+ adapter.unwrap().info("request at url = {} resulted in http response: {}", openstackIdentityUrl,
+ result.getResult());
+
+ String token = result.getHeaders().getFirst(X_SUBJECT_TOKEN);
+
+ if (token == null) {
+ throw new ApplicationException(UNAUTHORIZED, Status.UNAUTHORIZED);
+ }
+
+ adapter.unwrap().debug("Got token: {}", token);
+
+ return token;
+ }
+
+}
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/SpringServiceImpl.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/SpringServiceImpl.java
index 8d0de03..1be8fbc 100644
--- a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/SpringServiceImpl.java
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/SpringServiceImpl.java
@@ -17,16 +17,17 @@
*/
package org.onap.sdnc.apps.pomba.networkdiscovery.service;
+import com.bazaarvoice.jolt.JsonUtils;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
+
import java.io.IOException;
-import java.io.StringReader;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
-import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+
import javax.annotation.PreDestroy;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Entity;
@@ -37,13 +38,13 @@ 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 javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
+
import org.onap.aai.restclient.client.OperationResult;
import org.onap.aai.restclient.client.RestClient;
import org.onap.logging.ref.slf4j.ONAPLogAdapter;
import org.onap.logging.ref.slf4j.ONAPLogAdapter.RequestBuilder;
+import org.onap.logging.ref.slf4j.ONAPLogConstants;
import org.onap.logging.ref.slf4j.ONAPLogConstants.InvocationMode;
import org.onap.pomba.common.datatypes.DataQuality;
import org.onap.sdnc.apps.pomba.networkdiscovery.ApplicationException;
@@ -51,64 +52,56 @@ import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute;
import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.NetworkDiscoveryNotification;
import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.NetworkDiscoveryResponse;
import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Resource;
-import org.onap.sdnc.apps.pomba.networkdiscovery.service.rs.RestService;
+import org.onap.sdnc.apps.pomba.networkdiscovery.service.util.TransformationUtil;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
@Service
public class SpringServiceImpl implements SpringService {
- private static final String ENRICHER_HEADER_APPLICATION = "X-FromAppId";
- private static final String ENRICHER_HEADER_TRANSACTION = "X-TransactionId";
-
+ private static final String OPENSTACK_HEADER_TOKEN = "X-Auth-Token";
+ private static final String OPENSTACK_HEADER_API_VERSION = "X-OpenStack-Nova-API-Version";
private static final int DEFAULT_WORKER_THREADS = 3;
private ExecutorService executor = Executors.newFixedThreadPool(
- Integer.getInteger("discovery.threads", DEFAULT_WORKER_THREADS),
- new ThreadFactoryBuilder().setNameFormat("discovery-worker-%d").build());
+ Integer.getInteger("discovery.threads", DEFAULT_WORKER_THREADS),
+ new ThreadFactoryBuilder().setNameFormat("discovery-worker-%d").build());
@Autowired
- private RestClient enricherClient;
+ private RestClient openstackClient;
@Autowired
- private String enricherBaseUrl;
+ private String openstackIdentityUrl;
- @javax.annotation.Resource
- private Client callbackClient;
+ @Autowired
+ private String openstackIdentityUser;
- @javax.annotation.Resource
- private Map<String, String> enricherTypeURLs;
+ @Autowired
+ private String openstackIdentityPassword;
+
+ @Autowired
+ private String openstackApiMicroversion;
- private DocumentBuilder parser;
+ @javax.annotation.Resource
+ private Client callbackClient;
@javax.annotation.Resource
- private Map<String, String> enricherAttributeNameMapping;
+ private Map<String, String> openstackTypeURLs;
public SpringServiceImpl() throws ParserConfigurationException {
- this.parser = DocumentBuilderFactory.newInstance().newDocumentBuilder();
}
@Override
- public NetworkDiscoveryResponse findbyResourceIdAndType(String transactionId,
- String requestId,
- String resourceType,
- List<String> resourceIds,
- String notificationURL,
- String notificationAuthorization,
- ONAPLogAdapter adapter) throws ApplicationException {
+ public NetworkDiscoveryResponse findbyResourceIdAndType(String transactionId, String requestId, String resourceType,
+ List<String> resourceIds, String notificationURL, String notificationAuthorization, ONAPLogAdapter adapter)
+ throws ApplicationException {
NetworkDiscoveryResponse response = new NetworkDiscoveryResponse();
response.setRequestId(requestId);
- String enricherURL = this.enricherTypeURLs.get(resourceType);
+ String openstackURL = this.openstackTypeURLs.get(resourceType);
// check if resourceType is supported
- if (enricherURL == null) {
+ if (openstackURL == null) {
// don't know what to do with this - return empty response
response.setCode(Status.NO_CONTENT.getStatusCode());
response.setMessage("Unsupported resourceType " + resourceType);
@@ -118,7 +111,7 @@ public class SpringServiceImpl implements SpringService {
// schedule discovery of specified resources
Runnable task = new ResourceTask(transactionId, requestId, resourceType, resourceIds, notificationURL,
- notificationAuthorization, enricherURL, adapter);
+ notificationAuthorization, openstackURL, adapter);
this.executor.submit(task);
response.setCode(Status.ACCEPTED.getStatusCode());
@@ -132,65 +125,29 @@ public class SpringServiceImpl implements SpringService {
this.executor.shutdown();
}
- private void sendNotification(String url, String authorization, Object notification, ONAPLogAdapter adapter) {
+ private void sendNotification(String url, String transactionId, String authorization, Object notification,
+ ONAPLogAdapter adapter) {
Invocation.Builder request = this.callbackClient.target(url).request().accept(MediaType.TEXT_PLAIN_TYPE);
if (authorization != null) {
request.header(HttpHeaders.AUTHORIZATION, authorization);
+ request.header(ONAPLogConstants.Headers.REQUEST_ID, transactionId);
}
Logger log = adapter.unwrap();
adapter.invoke(new RequestBuilderWrapper(request), InvocationMode.SYNCHRONOUS);
try {
- // native client marshaller doesn't skip null fields
- // so manually marshal notification to json
-
- if (log.isDebugEnabled()) {
- StringBuilder debugRequest = new StringBuilder("REQUEST:\n");
- debugRequest.append("URL: ").append(url).append("\n");
- debugRequest.append("Payload: ").append(notification).append("\n");
- // if (headers != null) {
- // debugRequest.append("Headers: ");
- // for (Entry<String, List<String>> header : headers.entrySet())
- // {
- // debugRequest.append("\n\t").append(header.getKey()).append(":");
- // for (String headerEntry : header.getValue()) {
- // debugRequest.append("\"").append(headerEntry).append("\" ");
- // }
- // }
- // }
- log.debug(debugRequest.toString());
- }
+ adapter.unwrap().info("Posting notfication to url = {} , payload: {}", url,
+ JsonUtils.toJsonString(Entity.json(notification).getEntity()));
Response result = request.post(Entity.json(notification));
- adapter.unwrap().info("request at url = {} resulted in http response: {}", url,
- result.getStatusInfo().getStatusCode() + " " + result.getStatusInfo().getReasonPhrase());
-
- if (log.isDebugEnabled()) {
- StringBuilder debugResponse = new StringBuilder("RESPONSE:\n");
- debugResponse.append("Result: ").append(result.getStatus()).append("\n");
- String content = result.hasEntity() ? result.getEntity().toString() : null;
- if (result.getStatus() >= 300) {
- debugResponse.append("Failure Cause: ").append(content).append("\n");
- } else {
- debugResponse.append("Payload: ").append(content).append("\n");
- }
- if (result.getHeaders() != null) {
- debugResponse.append("Headers: ");
- for (Entry<String, List<Object>> header : result.getHeaders().entrySet()) {
- debugResponse.append("\n\t").append(header.getKey()).append(":");
- for (Object headerEntry : header.getValue()) {
- debugResponse.append("\"").append(headerEntry).append("\" ");
- }
- }
- }
- log.debug(debugResponse.toString());
- }
+ adapter.unwrap().info("request at url = {} resulted in http status {} and response: {}", url,
+ result.getStatus(), result.getEntity());
} catch (Exception x) {
log.error("Error during {} operation to endpoint at url = {} with error = {}", "POST", url,
- x.getLocalizedMessage());
+ x.getLocalizedMessage());
}
}
@@ -204,14 +161,8 @@ public class SpringServiceImpl implements SpringService {
private final String resourceURL;
private final ONAPLogAdapter adapter;
- public ResourceTask(String transactionId,
- String requestId,
- String resourceType,
- List<String> resourceIds,
- String notificationURL,
- String notificationAuthorization,
- String resourceURL,
- ONAPLogAdapter adapter) {
+ public ResourceTask(String transactionId, String requestId, String resourceType, List<String> resourceIds,
+ String notificationURL, String notificationAuthorization, String resourceURL, ONAPLogAdapter adapter) {
this.transactionId = transactionId;
this.requestId = requestId;
this.resourceType = resourceType;
@@ -224,19 +175,45 @@ public class SpringServiceImpl implements SpringService {
@Override
public void run() {
+ try {
+ runResourceDiscoveryTask();
+ } catch (Exception e) {
+ Logger log = adapter.unwrap();
+ log.error("Failure in resource task", e);
+
+ // Try to send out a notification of the failure:
+ NetworkDiscoveryNotification notification = new NetworkDiscoveryNotification();
+ notification.setRequestId(this.requestId);
+ notification.setCode(Status.INTERNAL_SERVER_ERROR.getStatusCode());
+ notification.setMessage(e.getMessage());
+ notification.setAckFinalIndicator(true);
+
+ // call client back with resource details
+ sendNotification(this.notificationURL, this.transactionId, this.notificationAuthorization, notification,
+ adapter);
+ }
+ }
+
+ private void runResourceDiscoveryTask() throws IOException, ApplicationException {
+
+ String token = OSAuthentication.getToken(openstackIdentityUrl, openstackIdentityUser,
+ openstackIdentityPassword, openstackClient, adapter);
+
NetworkDiscoveryNotification notification = new NetworkDiscoveryNotification();
notification.setRequestId(this.requestId);
List<Resource> resources = null;
- MessageFormat format = new MessageFormat(SpringServiceImpl.this.enricherBaseUrl + this.resourceURL);
+ MessageFormat format = new MessageFormat(this.resourceURL);
MultivaluedMap<String, String> headers = new MultivaluedHashMap<>();
- headers.add(ENRICHER_HEADER_APPLICATION, RestService.SERVICE_NAME);
- headers.add(ENRICHER_HEADER_TRANSACTION, this.transactionId);
+ headers.add(OPENSTACK_HEADER_TOKEN, token);
+ headers.add(OPENSTACK_HEADER_API_VERSION, openstackApiMicroversion);
for (String resourceId : this.resourceIds) {
String url = format.format(new Object[] { resourceId });
- OperationResult result = SpringServiceImpl.this.enricherClient.get(url, headers,
- MediaType.APPLICATION_XML_TYPE);
+ OperationResult result = SpringServiceImpl.this.openstackClient.get(url, headers,
+ MediaType.APPLICATION_JSON_TYPE);
+
+ adapter.unwrap().info("Openstack GET result: {}", result.getResult());
Resource resource = new Resource();
resource.setType(this.resourceType);
@@ -248,13 +225,13 @@ public class SpringServiceImpl implements SpringService {
resources.add(resource);
if (result.wasSuccessful()) {
+ String transformedOutput = TransformationUtil.transform(result.getResult(), this.resourceType);
+
+ adapter.unwrap().info("Jolt transformed output: {}", transformedOutput);
+
resource.setDataQuality(DataQuality.ok());
- try {
- List<Attribute> attributeList = toAttributeList(result.getResult(), adapter);
- resource.setAttributeList(attributeList);
- } catch (Exception x) {
- resource.setDataQuality(DataQuality.error(x.getMessage()));
- }
+ List<Attribute> attributeList = TransformationUtil.toAttributeList(transformedOutput);
+ resource.setAttributeList(attributeList);
} else {
resource.setDataQuality(DataQuality.error(result.getFailureCause()));
}
@@ -264,37 +241,8 @@ public class SpringServiceImpl implements SpringService {
notification.setAckFinalIndicator(true);
// call client back with resource details
- sendNotification(this.notificationURL, this.notificationAuthorization, notification, adapter);
- }
-
- private List<Attribute> toAttributeList(String xml, ONAPLogAdapter adapter) throws SAXException, IOException {
- Logger log = adapter.unwrap();
- Document doc = parser.parse(new InputSource(new StringReader(xml)));
- NodeList children = doc.getDocumentElement().getChildNodes();
- List<Attribute> result = new ArrayList<>();
- for (int i = 0; i < children.getLength(); i++) {
- Node child = children.item(i);
- if (child.getNodeType() == Node.ELEMENT_NODE) {
-
- // remove white space before conversion
- String attributeName = ((Element) child).getTagName().replaceAll("\\s", "");
-
- // If the incoming attribute name is not listed in the
- // attributeNameMapping, then this attribute will be removed.
- String newName = enricherAttributeNameMapping.get(attributeName);
- if (newName != null) {
- Attribute attr = new Attribute();
- attr.setName(newName);
- attr.setValue(((Element) child).getTextContent());
- attr.setDataQuality(DataQuality.ok());
- result.add(attr);
- } else {
- log.debug("[" + ((Element) child).getTagName()
- + "] was removed due to not listed in enricherAttributeNameMapping.");
- }
- }
- }
- return result;
+ sendNotification(this.notificationURL, this.transactionId, this.notificationAuthorization, notification,
+ adapter);
}
}
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/rs/RestServiceImpl.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/rs/RestServiceImpl.java
index 7447e67..0677dcd 100644
--- a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/rs/RestServiceImpl.java
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/rs/RestServiceImpl.java
@@ -64,14 +64,13 @@ public class RestServiceImpl implements RestService {
String notificationURL) throws ApplicationException {
ONAPLogAdapter adapter = new ONAPLogAdapter(log);
- adapter.getServiceDescriptor().setServiceName(SERVICE_NAME);
- adapter.entering(request);
+
try {
+ adapter.getServiceDescriptor().setServiceName(SERVICE_NAME);
+ adapter.entering(request);
if (version == null) {
- // only unit tests can pass null here
- // url matching will guarantee non-null in real server
- version = "v1";
+ throw new ApplicationException(MISSING_PARAM, Status.BAD_REQUEST, "version");
}
if (authorization == null || !this.basicAuthHeader.equals(authorization)) {
@@ -95,7 +94,7 @@ public class RestServiceImpl implements RestService {
if (transactionId == null || transactionId.isEmpty()) {
transactionId = UUID.randomUUID().toString();
- log.debug("transactionId is missing; using newly generated value: " + transactionId);
+ log.debug("transactionId is missing; using newly generated value: {}", transactionId);
}
// just reuse received Authorization header in callback
diff --git a/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/util/TransformationUtil.java b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/util/TransformationUtil.java
new file mode 100644
index 0000000..dc17848
--- /dev/null
+++ b/pomba/network-discovery/src/main/java/org/onap/sdnc/apps/pomba/networkdiscovery/service/util/TransformationUtil.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2014 Bazaarvoice, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onap.sdnc.apps.pomba.networkdiscovery.service.util;
+
+import com.bazaarvoice.jolt.Chainr;
+import com.bazaarvoice.jolt.JsonUtils;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import org.onap.pomba.common.datatypes.DataQuality;
+import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute;
+
+public class TransformationUtil {
+
+ private static final String CONFIG_JOLT = "config/jolt";
+ private static final String EMPTY_STRING = "";
+
+ public TransformationUtil() {
+ throw new IllegalStateException("Utility class");
+ }
+
+ /**
+ * Transforms the sourceJson using the jolt specification for the given resourceType.
+ *
+ * @param sourceJson
+ * @param resourceType
+ * @return
+ */
+ public static String transform(String sourceJson, String resourceType) {
+
+ Object sourceObject = JsonUtils.jsonToObject(sourceJson);
+
+ List<Object> chainrSpecJSON = JsonUtils.filepathToList(CONFIG_JOLT + File.separator + resourceType + ".json");
+ Chainr chainr = Chainr.fromSpec(chainrSpecJSON);
+ Object output = chainr.transform(sourceObject);
+
+ return JsonUtils.toJsonString(output);
+ }
+
+ /**
+ * Converts the second level of JsonElements from the given json to a list of
+ * Network Discovery Attributes.
+ *
+ * @param json
+ * @return
+ */
+ public static List<Attribute> toAttributeList(String json) {
+
+ JsonParser parser = new JsonParser();
+ JsonElement elem = parser.parse(json);
+
+ Set<Entry<String, JsonElement>> entrySet = elem.getAsJsonObject().entrySet();
+
+ List<Attribute> result = new ArrayList<>();
+
+ Iterator<Entry<String, JsonElement>> iter = entrySet.iterator();
+ while (iter.hasNext()) {
+ Entry<String, JsonElement> next = iter.next();
+
+ JsonElement vserverElem = next.getValue();
+ Set<Entry<String, JsonElement>> vserverEntrySet = vserverElem.getAsJsonObject().entrySet();
+ Iterator<Entry<String, JsonElement>> vserverIter = vserverEntrySet.iterator();
+ while (vserverIter.hasNext()) {
+ Entry<String, JsonElement> vserverNext = vserverIter.next();
+ Attribute attr = new Attribute();
+ attr.setName(vserverNext.getKey());
+ if (vserverNext.getValue().isJsonNull()) {
+ attr.setValue(EMPTY_STRING);
+ } else {
+ attr.setValue(vserverNext.getValue().getAsString());
+ }
+ attr.setDataQuality(DataQuality.ok());
+ result.add(attr);
+ }
+ }
+ return result;
+ }
+
+} \ No newline at end of file
diff --git a/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/NetworkDiscoveryTest.java b/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/NetworkDiscoveryTest.java
index 1829e6e..18a0a04 100644
--- a/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/NetworkDiscoveryTest.java
+++ b/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/NetworkDiscoveryTest.java
@@ -20,7 +20,7 @@ package org.onap.sdnc.apps.pomba.networkdiscovery.unittest.service;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.ok;
-import static com.github.tomakehurst.wiremock.client.WireMock.okTextXml;
+import static com.github.tomakehurst.wiremock.client.WireMock.okJson;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static org.junit.Assert.assertEquals;
@@ -28,13 +28,16 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import com.bazaarvoice.jolt.JsonUtils;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;
+import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.junit.WireMockRule;
import com.github.tomakehurst.wiremock.stubbing.ServeEvent;
import com.github.tomakehurst.wiremock.verification.LoggedRequest;
+
import java.net.URISyntaxException;
import java.text.MessageFormat;
import java.util.ArrayList;
@@ -42,16 +45,19 @@ import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.UUID;
+
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
+
import org.eclipse.jetty.util.security.Password;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.mockito.Mockito;
import org.onap.logging.ref.slf4j.ONAPLogConstants;
import org.onap.pomba.common.datatypes.DataQuality;
import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute;
@@ -64,7 +70,6 @@ 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.core.env.Environment;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@@ -73,11 +78,13 @@ import org.springframework.test.context.web.WebAppConfiguration;
@EnableAutoConfiguration(exclude = { DataSourceAutoConfiguration.class, HibernateJpaAutoConfiguration.class })
@WebAppConfiguration
@SpringBootTest
-@TestPropertySource(properties = { "enricher.url=http://localhost:9505",
+@TestPropertySource(properties = { "openstack.type.vserver.url=http://localhost:8774/v2.1/servers/{0}",
+ "openstack.identity.url=http://localhost:5000/v3/auth/tokens",
"enricher.keyStorePath=src/test/resources/client-cert-onap.p12",
"enricher.keyStorePassword=OBF:1y0q1uvc1uum1uvg1pil1pjl1uuq1uvk1uuu1y10",
"basicAuth.username=admin",
"basicAuth.password=OBF:1u2a1toa1w8v1tok1u30" })
+
public class NetworkDiscoveryTest {
private static final String V1 = "v1";
private static final String APP = "junit";
@@ -87,11 +94,12 @@ public class NetworkDiscoveryTest {
private static final String AUTH = "Basic " + Base64.getEncoder().encodeToString((
"admin:" + Password.deobfuscate("OBF:1u2a1toa1w8v1tok1u30")).getBytes());
- @Autowired
- private Environment environment;
@Rule
- public WireMockRule enricherRule = new WireMockRule(wireMockConfig().port(9505));
+ public WireMockRule identityRule = new WireMockRule(wireMockConfig().port(5000));
+
+ @Rule
+ public WireMockRule openstackRule = new WireMockRule(wireMockConfig().port(8774));
@Rule
public WireMockRule callbackRule = new WireMockRule(wireMockConfig().dynamicPort());
@@ -101,7 +109,10 @@ public class NetworkDiscoveryTest {
private String transactionId = UUID.randomUUID().toString();
private String requestId = UUID.randomUUID().toString();
- private HttpServletRequest httpRequest = new TestHttpServletRequest();
+ private HttpServletRequest httpRequest = Mockito.mock(HttpServletRequest.class);
+
+ private static final String TEST_RESOURCES = "src/test/resources/jolt/";
+
public NetworkDiscoveryTest() throws URISyntaxException {
@@ -139,6 +150,18 @@ public class NetworkDiscoveryTest {
}
@Test
+ public void testNoVersion() throws Exception {
+ // no Authorization header
+ String authorization = "Basic " + Base64.getEncoder().encodeToString("aaa:bbb".getBytes());
+ List<String> resourceIds = Arrays.asList(UUID.randomUUID().toString());
+ Response response = this.service.findbyResourceIdAndType(this.httpRequest, null, authorization, APP,
+ this.transactionId, this.requestId, RESOURCE_TYPE_VSERVER, resourceIds, getCallbackUrl());
+ assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+ // should get WWW-Authenticate header in response
+ assertTrue(((String) response.getEntity()).contains("version"));
+ }
+
+ @Test
public void testVerifyAppId() throws Exception {
// no X-FromAppId header
List<String> resourceIds = Arrays.asList(UUID.randomUUID().toString());
@@ -150,7 +173,6 @@ public class NetworkDiscoveryTest {
@Test
public void testVerifyRequestId() throws Exception {
- // no X-FromAppId header
List<String> resourceIds = Arrays.asList(UUID.randomUUID().toString());
Response response = this.service.findbyResourceIdAndType(this.httpRequest, V1, AUTH, APP, this.transactionId,
null, RESOURCE_TYPE_VSERVER, resourceIds, getCallbackUrl());
@@ -160,7 +182,6 @@ public class NetworkDiscoveryTest {
@Test
public void testVerifyNotificationUrl() throws Exception {
- // no X-FromAppId header
List<String> resourceIds = Arrays.asList(UUID.randomUUID().toString());
Response response = this.service.findbyResourceIdAndType(this.httpRequest, V1, AUTH, APP, this.transactionId,
this.requestId, RESOURCE_TYPE_VSERVER, resourceIds, null);
@@ -200,31 +221,31 @@ public class NetworkDiscoveryTest {
}
@Test
+ public void testVerifyInternalError() throws Exception {
+ // no request
+ List<String> resourceIds = Arrays.asList(UUID.randomUUID().toString());
+ Response response = this.service.findbyResourceIdAndType(null, V1, AUTH, APP, this.transactionId,
+ this.requestId, null, resourceIds, getCallbackUrl());
+ assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), response.getStatus());
+ }
+
+ @Test
public void testDiscoverVserver() throws Exception {
String vserverId = UUID.randomUUID().toString();
- String resourcePath = MessageFormat.format(
- this.environment.getProperty("enricher.type.vserver.url"),
- new Object[] { vserverId });
-
- String enricherPayload = String.format("<vserver xmlns=\"http://org.onap.aai.inventory/v11\">\r\n"
- + " <vserver-id>%s</vserver-id>\r\n"
- + " <power-state>1</power-state>\r\n"
- + " <locked>true</locked>\r\n"
- + " <hostname>10.147.112.48</hostname>\r\n"
- + " <vm-state>active</vm-state>\r\n"
- + " <status>ACTIVE</status>\r\n"
- + " <host-status>UNKNOWN</host-status>\r\n"
- + " <updated>2017-11-20T04:26:13Z</updated>\r\n"
- + " <disk-allocation-gb>.010</disk-allocation-gb>\r\n"
- + " <memory-usage-mb>null</memory-usage-mb>\r\n"
- + " <cpu-util-percent>.043</cpu-util-percent>\r\n"
- + " <retrieval-timestamp>2018-06-27 19:41:49 +0000</retrieval-timestamp>\r\n"
- + "</vserver>",
- vserverId);
-
- this.enricherRule.stubFor(get(resourcePath).willReturn(okTextXml(enricherPayload)));
+ String resourcePath = MessageFormat.format("/v2.1/servers/{0}",
+ new Object[] { vserverId });
+ String identityPath = "/v3/auth/tokens";
+
+ Object sourceObject = JsonUtils.filepathToObject(TEST_RESOURCES + "vserver-input.json");
+
+ String openstackApiResponse = JsonUtils.toJsonString(sourceObject);
+
+ this.openstackRule.stubFor(get(resourcePath).willReturn(okJson(openstackApiResponse)));
+
+ this.identityRule.stubFor(post(identityPath).willReturn(okJson("{}").withHeader("X-Subject-Token", "tokenId")));
+
this.callbackRule.stubFor(post(CALLBACK_PATH).willReturn(ok("Acknowledged")));
Response response = this.service.findbyResourceIdAndType(this.httpRequest, V1, AUTH, APP, null, this.requestId,
@@ -259,9 +280,57 @@ public class NetworkDiscoveryTest {
verifyAttribute(vserver.getAttributeList(), "status", "ACTIVE");
verifyAttribute(vserver.getAttributeList(), "inMaintenance", "true");
- verifyAttribute(vserver.getAttributeList(), "hostName", "10.147.112.48");
+ verifyAttribute(vserver.getAttributeList(), "hostname", "norm-bouygues");
verifyAttribute(vserver.getAttributeList(), "vmState", "active");
}
+
+ @Test
+ public void testDiscoverVserverFailure() throws Exception {
+ String vserverId = UUID.randomUUID().toString();
+
+ String resourcePath = MessageFormat.format("/v2.1/servers/{0}",
+ new Object[] { vserverId });
+
+ String identityPath = "/v3/auth/tokens";
+
+ this.openstackRule.stubFor(get(resourcePath).willReturn(WireMock.notFound()));
+
+ this.identityRule.stubFor(post(identityPath).willReturn(okJson("{}").withHeader("X-Subject-Token", "tokenId")));
+
+ this.callbackRule.stubFor(post(CALLBACK_PATH).willReturn(ok("Acknowledged")));
+
+ Response response = this.service.findbyResourceIdAndType(this.httpRequest, V1, AUTH, APP, null, this.requestId,
+ RESOURCE_TYPE_VSERVER, Arrays.asList(vserverId), getCallbackUrl());
+
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ NetworkDiscoveryResponse entity = (NetworkDiscoveryResponse) response.getEntity();
+ assertEquals(requestId, entity.getRequestId());
+ assertEquals(Status.ACCEPTED.getStatusCode(), entity.getCode().intValue());
+ assertEquals(Boolean.FALSE, entity.getAckFinalIndicator());
+
+ List<ServeEvent> events = waitForRequests(this.callbackRule, 1, 10);
+ LoggedRequest notificationRequest = events.get(0).getRequest();
+ assertEquals(AUTH, notificationRequest.getHeader(HttpHeaders.AUTHORIZATION));
+ String notificationJson = notificationRequest.getBodyAsString();
+
+ ObjectMapper mapper = new ObjectMapper();
+ AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
+ mapper.setAnnotationIntrospector(introspector);
+ NetworkDiscoveryNotification notification = mapper.readValue(notificationJson,
+ NetworkDiscoveryNotification.class);
+
+ assertEquals(requestId, notification.getRequestId());
+ assertEquals(Status.OK.getStatusCode(), notification.getCode().intValue());
+ assertEquals(Boolean.TRUE, notification.getAckFinalIndicator());
+
+ assertEquals(1, notification.getResources().size());
+ Resource vserver = notification.getResources().get(0);
+ assertEquals(vserverId, vserver.getId());
+ assertEquals("vserver", vserver.getType());
+ assertEquals(DataQuality.Status.error, vserver.getDataQuality().getStatus());
+ assertNull(vserver.getAttributeList());
+ }
+
/**
* Verify API returns a final response indicating no discovery possible.
@@ -276,9 +345,47 @@ public class NetworkDiscoveryTest {
assertEquals(Status.OK.getStatusCode(), response.getStatus());
NetworkDiscoveryResponse entity = (NetworkDiscoveryResponse) response.getEntity();
+ System.err.println("entity:" + entity);
assertEquals(Boolean.TRUE, entity.getAckFinalIndicator());
assertEquals(Status.NO_CONTENT.getStatusCode(), entity.getCode().intValue());
}
+
+ @Test
+ public void testLoginFailure() throws Exception {
+ String vserverId = UUID.randomUUID().toString();
+
+ String identityPath = "/v3/auth/tokens";
+
+ this.identityRule.stubFor(post(identityPath).willReturn(WireMock.unauthorized()));
+
+ this.callbackRule.stubFor(post(CALLBACK_PATH).willReturn(ok("Acknowledged")));
+
+ Response response = this.service.findbyResourceIdAndType(this.httpRequest, V1, AUTH, APP, null, this.requestId,
+ RESOURCE_TYPE_VSERVER, Arrays.asList(vserverId), getCallbackUrl());
+
+ assertEquals(Status.OK.getStatusCode(), response.getStatus());
+ NetworkDiscoveryResponse entity = (NetworkDiscoveryResponse) response.getEntity();
+ assertEquals(requestId, entity.getRequestId());
+ assertEquals(Status.ACCEPTED.getStatusCode(), entity.getCode().intValue());
+ assertEquals(Boolean.FALSE, entity.getAckFinalIndicator());
+
+ List<ServeEvent> events = waitForRequests(this.callbackRule, 1, 10);
+ LoggedRequest notificationRequest = events.get(0).getRequest();
+ assertEquals(AUTH, notificationRequest.getHeader(HttpHeaders.AUTHORIZATION));
+ String notificationJson = notificationRequest.getBodyAsString();
+
+ ObjectMapper mapper = new ObjectMapper();
+ AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
+ mapper.setAnnotationIntrospector(introspector);
+ NetworkDiscoveryNotification notification = mapper.readValue(notificationJson,
+ NetworkDiscoveryNotification.class);
+
+ assertEquals(requestId, notification.getRequestId());
+ assertEquals(Status.INTERNAL_SERVER_ERROR.getStatusCode(), notification.getCode().intValue());
+ assertEquals(Boolean.TRUE, notification.getAckFinalIndicator());
+ assertNull(notification.getResources());
+ }
+
private void verifyAttribute(List<Attribute> attributeList, String attrName, String attrValue) {
for (Attribute attr : attributeList) {
diff --git a/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/TestHttpServletRequest.java b/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/TestHttpServletRequest.java
deleted file mode 100644
index 671033b..0000000
--- a/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/TestHttpServletRequest.java
+++ /dev/null
@@ -1,500 +0,0 @@
-/*
- * ============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.sdnc.apps.pomba.networkdiscovery.unittest.service;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.Principal;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Locale;
-import java.util.Map;
-import javax.servlet.AsyncContext;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletContext;
-import javax.servlet.ServletException;
-import javax.servlet.ServletInputStream;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-import javax.servlet.http.HttpUpgradeHandler;
-import javax.servlet.http.Part;
-
-public class TestHttpServletRequest implements HttpServletRequest {
- @Override
- public String getHeader(String name) {
- return null;
- }
-
- @Override
- public String getRemoteAddr() {
- return "localhost";
- }
-
- @Override
- public String getServerName() {
- return "localhost";
- }
-
- @Override
- public String getRequestURI() {
- return "/test";
- }
-
-
- @Override
- public Object getAttribute(String name) {
- // TODO Implement getAttribute
- throw new UnsupportedOperationException("getAttribute");
- }
-
- @Override
- public Enumeration<String> getAttributeNames() {
- // TODO Implement getAttributeNames
- throw new UnsupportedOperationException("getAttributeNames");
- }
-
- @Override
- public String getCharacterEncoding() {
- // TODO Implement getCharacterEncoding
- throw new UnsupportedOperationException("getCharacterEncoding");
- }
-
- @Override
- public void setCharacterEncoding(String env) throws UnsupportedEncodingException {
- // TODO Implement setCharacterEncoding
- throw new UnsupportedOperationException("setCharacterEncoding");
- }
-
- @Override
- public int getContentLength() {
- // TODO Implement getContentLength
- throw new UnsupportedOperationException("getContentLength");
- }
-
- @Override
- public long getContentLengthLong() {
- // TODO Implement getContentLengthLong
- throw new UnsupportedOperationException("getContentLengthLong");
- }
-
- @Override
- public String getContentType() {
- // TODO Implement getContentType
- throw new UnsupportedOperationException("getContentType");
- }
-
- @Override
- public ServletInputStream getInputStream() throws IOException {
- // TODO Implement getInputStream
- throw new UnsupportedOperationException("getInputStream");
- }
-
- @Override
- public String getParameter(String name) {
- // TODO Implement getParameter
- throw new UnsupportedOperationException("getParameter");
- }
-
- @Override
- public Enumeration<String> getParameterNames() {
- // TODO Implement getParameterNames
- throw new UnsupportedOperationException("getParameterNames");
- }
-
- @Override
- public String[] getParameterValues(String name) {
- // TODO Implement getParameterValues
- throw new UnsupportedOperationException("getParameterValues");
- }
-
- @Override
- public Map<String, String[]> getParameterMap() {
- // TODO Implement getParameterMap
- throw new UnsupportedOperationException("getParameterMap");
- }
-
- @Override
- public String getProtocol() {
- // TODO Implement getProtocol
- throw new UnsupportedOperationException("getProtocol");
- }
-
- @Override
- public String getScheme() {
- // TODO Implement getScheme
- throw new UnsupportedOperationException("getScheme");
- }
-
- @Override
- public int getServerPort() {
- // TODO Implement getServerPort
- throw new UnsupportedOperationException("getServerPort");
- }
-
- @Override
- public BufferedReader getReader() throws IOException {
- // TODO Implement getReader
- throw new UnsupportedOperationException("getReader");
- }
-
- @Override
- public String getRemoteHost() {
- // TODO Implement getRemoteHost
- throw new UnsupportedOperationException("getRemoteHost");
- }
-
- @Override
- public void setAttribute(String name, Object obj) {
- // TODO Implement setAttribute
- throw new UnsupportedOperationException("setAttribute");
- }
-
- @Override
- public void removeAttribute(String name) {
- // TODO Implement removeAttribute
- throw new UnsupportedOperationException("removeAttribute");
- }
-
- @Override
- public Locale getLocale() {
- // TODO Implement getLocale
- throw new UnsupportedOperationException("getLocale");
- }
-
- @Override
- public Enumeration<Locale> getLocales() {
- // TODO Implement getLocales
- throw new UnsupportedOperationException("getLocales");
- }
-
- @Override
- public boolean isSecure() {
- // TODO Implement isSecure
- throw new UnsupportedOperationException("isSecure");
- }
-
- @Override
- public RequestDispatcher getRequestDispatcher(String path) {
- // TODO Implement getRequestDispatcher
- throw new UnsupportedOperationException("getRequestDispatcher");
- }
-
- @Override
- public String getRealPath(String path) {
- // TODO Implement getRealPath
- throw new UnsupportedOperationException("getRealPath");
- }
-
- @Override
- public int getRemotePort() {
- // TODO Implement getRemotePort
- throw new UnsupportedOperationException("getRemotePort");
- }
-
- @Override
- public String getLocalName() {
- // TODO Implement getLocalName
- throw new UnsupportedOperationException("getLocalName");
- }
-
- @Override
- public String getLocalAddr() {
- // TODO Implement getLocalAddr
- throw new UnsupportedOperationException("getLocalAddr");
- }
-
- @Override
- public int getLocalPort() {
- // TODO Implement getLocalPort
- throw new UnsupportedOperationException("getLocalPort");
- }
-
- @Override
- public ServletContext getServletContext() {
- // TODO Implement getServletContext
- throw new UnsupportedOperationException("getServletContext");
- }
-
- @Override
- public AsyncContext startAsync() throws IllegalStateException {
- // TODO Implement startAsync
- throw new UnsupportedOperationException("startAsync");
- }
-
- @Override
- public AsyncContext startAsync(ServletRequest servletRequest, ServletResponse servletResponse)
- throws IllegalStateException {
- // TODO Implement startAsync
- throw new UnsupportedOperationException("startAsync");
- }
-
- @Override
- public boolean isAsyncStarted() {
- // TODO Implement isAsyncStarted
- throw new UnsupportedOperationException("isAsyncStarted");
- }
-
- @Override
- public boolean isAsyncSupported() {
- // TODO Implement isAsyncSupported
- throw new UnsupportedOperationException("isAsyncSupported");
- }
-
- @Override
- public AsyncContext getAsyncContext() {
- // TODO Implement getAsyncContext
- throw new UnsupportedOperationException("getAsyncContext");
- }
-
- @Override
- public DispatcherType getDispatcherType() {
- // TODO Implement getDispatcherType
- throw new UnsupportedOperationException("getDispatcherType");
- }
-
- @Override
- public String getAuthType() {
- // TODO Implement getAuthType
- throw new UnsupportedOperationException("getAuthType");
- }
-
- @Override
- public Cookie[] getCookies() {
- // TODO Implement getCookies
- throw new UnsupportedOperationException("getCookies");
- }
-
- @Override
- public long getDateHeader(String name) {
- // TODO Implement getDateHeader
- throw new UnsupportedOperationException("getDateHeader");
- }
-
- @Override
- public Enumeration<String> getHeaders(String name) {
- // TODO Implement getHeaders
- throw new UnsupportedOperationException("getHeaders");
- }
-
- @Override
- public Enumeration<String> getHeaderNames() {
- // TODO Implement getHeaderNames
- throw new UnsupportedOperationException("getHeaderNames");
- }
-
- @Override
- public int getIntHeader(String name) {
- // TODO Implement getIntHeader
- throw new UnsupportedOperationException("getIntHeader");
- }
-
- @Override
- public String getMethod() {
- // TODO Implement getMethod
- throw new UnsupportedOperationException("getMethod");
- }
-
- @Override
- public String getPathInfo() {
- // TODO Implement getPathInfo
- throw new UnsupportedOperationException("getPathInfo");
- }
-
- @Override
- public String getPathTranslated() {
- // TODO Implement getPathTranslated
- throw new UnsupportedOperationException("getPathTranslated");
- }
-
- @Override
- public String getContextPath() {
- // TODO Implement getContextPath
- throw new UnsupportedOperationException("getContextPath");
- }
-
- @Override
- public String getQueryString() {
- // TODO Implement getQueryString
- throw new UnsupportedOperationException("getQueryString");
- }
-
- @Override
- public String getRemoteUser() {
- // TODO Implement getRemoteUser
- throw new UnsupportedOperationException("getRemoteUser");
- }
-
- @Override
- public boolean isUserInRole(String role) {
- // TODO Implement isUserInRole
- throw new UnsupportedOperationException("isUserInRole");
- }
-
- @Override
- public Principal getUserPrincipal() {
- // TODO Implement getUserPrincipal
- throw new UnsupportedOperationException("getUserPrincipal");
- }
-
- @Override
- public String getRequestedSessionId() {
- // TODO Implement getRequestedSessionId
- throw new UnsupportedOperationException("getRequestedSessionId");
- }
-
- @Override
- public StringBuffer getRequestURL() {
- // TODO Implement getRequestURL
- throw new UnsupportedOperationException("getRequestURL");
- }
-
- @Override
- public String getServletPath() {
- // TODO Implement getServletPath
- throw new UnsupportedOperationException("getServletPath");
- }
-
- @Override
- public HttpSession getSession(boolean create) {
- // TODO Implement getSession
- throw new UnsupportedOperationException("getSession");
- }
-
- @Override
- public HttpSession getSession() {
- // TODO Implement getSession
- throw new UnsupportedOperationException("getSession");
- }
-
- @Override
- public String changeSessionId() {
- // TODO Implement changeSessionId
- throw new UnsupportedOperationException("changeSessionId");
- }
-
- @Override
- public boolean isRequestedSessionIdValid() {
- // TODO Implement isRequestedSessionIdValid
- throw new UnsupportedOperationException("isRequestedSessionIdValid");
- }
-
- @Override
- public boolean isRequestedSessionIdFromCookie() {
- // TODO Implement isRequestedSessionIdFromCookie
- throw new UnsupportedOperationException("isRequestedSessionIdFromCookie");
- }
-
- @Override
- public boolean isRequestedSessionIdFromURL() {
- // TODO Implement isRequestedSessionIdFromURL
- throw new UnsupportedOperationException("isRequestedSessionIdFromURL");
- }
-
- @Override
- public boolean isRequestedSessionIdFromUrl() {
- // TODO Implement isRequestedSessionIdFromUrl
- throw new UnsupportedOperationException("isRequestedSessionIdFromUrl");
- }
-
- @Override
- public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
- // TODO Implement authenticate
- throw new UnsupportedOperationException("authenticate");
- }
-
- @Override
- public void login(String username, String password) throws ServletException {
- // TODO Implement login
- throw new UnsupportedOperationException("login");
- }
-
- @Override
- public void logout() throws ServletException {
- // TODO Implement logout
- throw new UnsupportedOperationException("logout");
- }
-
- @Override
- public Collection<Part> getParts() throws IOException, ServletException {
- // TODO Implement getParts
- throw new UnsupportedOperationException("getParts");
- }
-
- @Override
- public Part getPart(String name) throws IOException, ServletException {
- // TODO Implement getPart
- throw new UnsupportedOperationException("getPart");
- }
-
- @Override
- public <T extends HttpUpgradeHandler> T upgrade(Class<T> httpUpgradeHandlerClass)
- throws IOException, ServletException {
- // TODO Implement upgrade
- throw new UnsupportedOperationException("upgrade");
- }
- /////////////////////////////////////////////////////////////////////////////
- // Constants
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Class variables
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Instance variables
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Constructors
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Public methods
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // [interface name] implementation
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // [super class] override methods
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Package protected methods
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Protected methods
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Private methods
- /////////////////////////////////////////////////////////////////////////////
-
- /////////////////////////////////////////////////////////////////////////////
- // Inner classes
- /////////////////////////////////////////////////////////////////////////////
-}
diff --git a/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/util/TransformationUtilTest.java b/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/util/TransformationUtilTest.java
new file mode 100644
index 0000000..968c1cf
--- /dev/null
+++ b/pomba/network-discovery/src/test/java/org/onap/sdnc/apps/pomba/networkdiscovery/unittest/service/util/TransformationUtilTest.java
@@ -0,0 +1,136 @@
+/*
+ * ============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.sdnc.apps.pomba.networkdiscovery.unittest.service.util;
+
+import static org.junit.Assert.assertThat;
+
+import com.bazaarvoice.jolt.JsonUtils;
+import com.bazaarvoice.jolt.exception.JsonUnmarshalException;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.onap.sdnc.apps.pomba.networkdiscovery.datamodel.Attribute;
+import org.onap.sdnc.apps.pomba.networkdiscovery.service.util.TransformationUtil;
+
+public class TransformationUtilTest {
+
+ private static final String TEST_RESOURCES = "src/test/resources/jolt/";
+
+ @Rule
+ public ExpectedException expectedEx = ExpectedException.none();
+
+ @Test
+ public void testTransformVServer() {
+
+ Object sourceObject = JsonUtils.filepathToObject(TEST_RESOURCES + "vserver-input.json");
+
+ String resultJson = TransformationUtil.transform(JsonUtils.toJsonString(sourceObject), "vserver");
+
+ Object expectedObject = JsonUtils.filepathToObject(TEST_RESOURCES + "vserver-expected.json");
+
+ Assert.assertEquals("Json transformation result does not match expected content",
+ JsonUtils.toPrettyJsonString(expectedObject),
+ JsonUtils.toPrettyJsonString(JsonUtils.jsonToObject(resultJson)));
+
+ }
+
+ @Test
+ public void testTransformL3Network() {
+
+ Object sourceObject = JsonUtils.filepathToObject(TEST_RESOURCES + "l3network-input.json");
+ String resultJson = TransformationUtil.transform(JsonUtils.toJsonString(sourceObject), "l3-network");
+
+ Object expectedObject = JsonUtils.filepathToObject(TEST_RESOURCES + "l3network-expected.json");
+
+ Assert.assertEquals("Json transformation result does not match expected content",
+ JsonUtils.toPrettyJsonString(expectedObject),
+ JsonUtils.toPrettyJsonString(JsonUtils.jsonToObject(resultJson)));
+
+ }
+
+ @Test
+ public void testTransformFailureFileNotFound() {
+
+ expectedEx.expect(RuntimeException.class);
+ expectedEx.expectMessage("Unable to load JSON file");
+
+ TransformationUtil.transform("{}", "foobar");
+ }
+
+ @Test
+ public void testTransformFailureInvalidInputJson() {
+
+ expectedEx.expect(JsonUnmarshalException.class);
+ expectedEx.expectMessage("Unable to unmarshal JSON");
+
+ TransformationUtil.transform("xxx", "foobar");
+ }
+
+ @Test
+ public void testToAttributeList() {
+ Map<String, String> expectedAttributes = new HashMap<String, String>();
+ expectedAttributes.put("name", "norm_bouygues");
+ expectedAttributes.put("hostId", "ea1660efbbedda164379afacdc622305c4b88cebfb84119472d286a8");
+ expectedAttributes.put("hostStatus", "UP");
+ expectedAttributes.put("id", "2c311eae-f542-4173-8a01-582922abd495");
+ expectedAttributes.put("status", "ACTIVE");
+ expectedAttributes.put("vmState", "active");
+ expectedAttributes.put("hostname", "norm-bouygues");
+ expectedAttributes.put("inMaintenance", "true");
+ expectedAttributes.put("imageId", "c0022890-d91f-422c-91c5-3866edeae768");
+ expectedAttributes.put("tenantId", "15ad36d394e744838e947ca90609f805");
+ expectedAttributes.put("host", "Setup-NCSO-OTT-E-C2");
+
+ Object inputJson = JsonUtils.filepathToObject(TEST_RESOURCES + "vserver-expected.json");
+ List<Attribute> resultAttributeList = TransformationUtil.toAttributeList(JsonUtils.toJsonString(inputJson));
+
+ Map<String, String> resultAttributes = new HashMap<>();
+
+ for (Attribute attribute : resultAttributeList) {
+ resultAttributes.put(attribute.getName(), attribute.getValue());
+ }
+ assertThat(expectedAttributes, CoreMatchers.is(resultAttributes));
+ }
+
+ @Test
+ public void testToAttributeListNullJsonValue() {
+ Map<String, String> expectedAttributes = new HashMap<String, String>();
+ expectedAttributes.put("name", "");
+
+ String inputJson = "{\"server\": { \"name\": null }}";
+
+ List<Attribute> resultAttributeList = TransformationUtil.toAttributeList(inputJson);
+
+ Map<String, String> resultAttributes = new HashMap<>();
+
+ for (Attribute attribute : resultAttributeList) {
+ resultAttributes.put(attribute.getName(), attribute.getValue());
+ }
+ // assertThat(expectedAttributes, resultAttributes);
+ assertThat(expectedAttributes, CoreMatchers.is(resultAttributes));
+ }
+
+}
diff --git a/pomba/network-discovery/src/test/resources/jolt/l3network-expected.json b/pomba/network-discovery/src/test/resources/jolt/l3network-expected.json
new file mode 100644
index 0000000..be4ad9d
--- /dev/null
+++ b/pomba/network-discovery/src/test/resources/jolt/l3network-expected.json
@@ -0,0 +1,14 @@
+{
+ "l3-network": {
+ "id": "8df84f0a-737a-4628-be9c-c3c78454f9d9",
+ "name": "NET_503",
+ "AdminState": true,
+ "sharedNetwork": true,
+ "status": "ACTIVE",
+ "subnets": [
+ "d0e6ecad-7bc9-4138-b9e8-e742bdf9afd5"
+ ],
+ "tenantId": "c44b872f6830498b88c4989d67b2a6b7",
+ "host-status": "UNKNOWN"
+ }
+}
diff --git a/pomba/network-discovery/src/test/resources/jolt/l3network-input.json b/pomba/network-discovery/src/test/resources/jolt/l3network-input.json
new file mode 100644
index 0000000..ebd9504
--- /dev/null
+++ b/pomba/network-discovery/src/test/resources/jolt/l3network-input.json
@@ -0,0 +1,32 @@
+{
+ "network": {
+ "provider:physical_network": "public",
+ "ipv6_address_scope": null,
+ "revision_number": 9,
+ "port_security_enabled": true,
+ "mtu": 1500,
+ "id": "8df84f0a-737a-4628-be9c-c3c78454f9d9",
+ "router:external": true,
+ "availability_zone_hints": [],
+ "availability_zones": [
+ "nova"
+ ],
+ "ipv4_address_scope": null,
+ "shared": true,
+ "project_id": "c44b872f6830498b88c4989d67b2a6b7",
+ "status": "ACTIVE",
+ "subnets": [
+ "d0e6ecad-7bc9-4138-b9e8-e742bdf9afd5"
+ ],
+ "description": "",
+ "tags": [],
+ "updated_at": "2018-10-03T21:15:10Z",
+ "is_default": false,
+ "provider:segmentation_id": 503,
+ "name": "NET_503",
+ "admin_state_up": true,
+ "tenant_id": "c44b872f6830498b88c4989d67b2a6b7",
+ "created_at": "2018-03-20T16:49:01Z",
+ "provider:network_type": "vlan"
+ }
+} \ No newline at end of file
diff --git a/pomba/network-discovery/src/test/resources/jolt/vserver-expected.json b/pomba/network-discovery/src/test/resources/jolt/vserver-expected.json
new file mode 100644
index 0000000..53d4a79
--- /dev/null
+++ b/pomba/network-discovery/src/test/resources/jolt/vserver-expected.json
@@ -0,0 +1,15 @@
+{
+ "vserver" : {
+ "id" : "2c311eae-f542-4173-8a01-582922abd495",
+ "name" : "norm_bouygues",
+ "inMaintenance" : true,
+ "hostname" : "norm-bouygues",
+ "imageId" : "c0022890-d91f-422c-91c5-3866edeae768",
+ "status" : "ACTIVE",
+ "vmState" : "active",
+ "tenantId" : "15ad36d394e744838e947ca90609f805",
+ "hostId" : "ea1660efbbedda164379afacdc622305c4b88cebfb84119472d286a8",
+ "host" : "Setup-NCSO-OTT-E-C2",
+ "hostStatus" : "UP"
+ }
+} \ No newline at end of file
diff --git a/pomba/network-discovery/src/test/resources/jolt/vserver-input.json b/pomba/network-discovery/src/test/resources/jolt/vserver-input.json
new file mode 100644
index 0000000..faa7ba5
--- /dev/null
+++ b/pomba/network-discovery/src/test/resources/jolt/vserver-input.json
@@ -0,0 +1,92 @@
+{
+ "server": {
+ "OS-EXT-STS:task_state": null,
+ "addresses": {
+ "NET_502": [
+ {
+ "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:a5:c5:19",
+ "version": 4,
+ "addr": "10.69.36.133",
+ "OS-EXT-IPS:type": "fixed"
+ },
+ {
+ "OS-EXT-IPS-MAC:mac_addr": "fa:16:3e:50:05:f4",
+ "version": 4,
+ "addr": "10.69.36.137",
+ "OS-EXT-IPS:type": "fixed"
+ }
+ ]
+ },
+ "links": [
+ {
+ "href": "http://10.69.36.11:8774/v2.1/servers/2c311eae-f542-4173-8a01-582922abd495",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.69.36.11:8774/servers/2c311eae-f542-4173-8a01-582922abd495",
+ "rel": "bookmark"
+ }
+ ],
+ "image": {
+ "id": "c0022890-d91f-422c-91c5-3866edeae768",
+ "links": [
+ {
+ "href": "http://10.69.36.11:8774/images/c0022890-d91f-422c-91c5-3866edeae768",
+ "rel": "bookmark"
+ }
+ ]
+ },
+ "OS-EXT-SRV-ATTR:user_data": null,
+ "OS-EXT-STS:vm_state": "active",
+ "OS-EXT-SRV-ATTR:instance_name": "instance-000009ca",
+ "OS-EXT-SRV-ATTR:root_device_name": "/dev/vda",
+ "OS-SRV-USG:launched_at": "2018-08-20T15:10:09.000000",
+ "flavor": {
+ "id": "786f55b2-7c94-4089-b89d-96353567c9d8",
+ "links": [
+ {
+ "href": "http://10.69.36.11:8774/flavors/786f55b2-7c94-4089-b89d-96353567c9d8",
+ "rel": "bookmark"
+ }
+ ]
+ },
+ "id": "2c311eae-f542-4173-8a01-582922abd495",
+ "security_groups": [
+ {
+ "name": "default"
+ },
+ {
+ "name": "default"
+ }
+ ],
+ "OS-SRV-USG:terminated_at": null,
+ "os-extended-volumes:volumes_attached": [],
+ "user_id": "bdaf4fcde1574450bfa488b3221033d8",
+ "OS-EXT-SRV-ATTR:hostname": "norm-bouygues",
+ "OS-DCF:diskConfig": "AUTO",
+ "accessIPv4": "",
+ "accessIPv6": "",
+ "OS-EXT-SRV-ATTR:reservation_id": "r-wo1numj9",
+ "progress": 0,
+ "OS-EXT-STS:power_state": 1,
+ "OS-EXT-AZ:availability_zone": "nova",
+ "metadata": {},
+ "status": "ACTIVE",
+ "OS-EXT-SRV-ATTR:ramdisk_id": "",
+ "updated": "2018-11-15T15:28:09Z",
+ "hostId": "ea1660efbbedda164379afacdc622305c4b88cebfb84119472d286a8",
+ "OS-EXT-SRV-ATTR:host": "Setup-NCSO-OTT-E-C2",
+ "description": "norm_bouygues",
+ "tags": [],
+ "key_name": "normant-test-key",
+ "OS-EXT-SRV-ATTR:kernel_id": "",
+ "locked": true,
+ "OS-EXT-SRV-ATTR:hypervisor_hostname": "Setup-NCSO-OTT-E-C2",
+ "name": "norm_bouygues",
+ "OS-EXT-SRV-ATTR:launch_index": 0,
+ "created": "2018-08-20T15:09:32Z",
+ "tenant_id": "15ad36d394e744838e947ca90609f805",
+ "host_status": "UP",
+ "config_drive": ""
+ }
+} \ No newline at end of file