diff options
author | 2018-11-27 22:18:16 +0000 | |
---|---|---|
committer | 2018-11-28 14:24:42 -0500 | |
commit | 9a0c9790a1dc31dcc2db199b6f0ff76e796c2597 (patch) | |
tree | 836a34fb2e4a8d1dd78cc9ed18553278c5a2ca1f /pomba/network-discovery | |
parent | 2f93fe9cf3c05d6606e37576121801dbdb98dd68 (diff) |
ND get VM info from Openstack
Issue-ID: SDNC-533
Change-Id: If50c4ae02349824a4e179e30ea1ee29d3afe6ab2
Signed-off-by: Norm Traxler <normant@amdocs.com>
Diffstat (limited to 'pomba/network-discovery')
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 Binary files differnew file mode 100644 index 0000000..dbf4fca --- /dev/null +++ b/pomba/network-discovery/config/auth/client-cert-onap.p12 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 |