Merge "Test ansible adaptor props"
authorDan Timoney <dt5972@att.com>
Fri, 7 Sep 2018 12:35:42 +0000 (12:35 +0000)
committerGerrit Code Review <gerrit@onap.org>
Fri, 7 Sep 2018 12:35:42 +0000 (12:35 +0000)
17 files changed:
aai-service/provider/src/main/resources/aai-path.properties
ansible-adapter/ansible-adapter-bundle/pom.xml
features/ccsdk-sli-adaptors-all/pom.xml
netbox-client/installer/pom.xml
netbox-client/installer/src/assembly/assemble_mvnrepo_zip.xml
netbox-client/provider/pom.xml
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java [new file with mode: 0644]
netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Status.java [deleted file]
netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml
netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplTest.java
netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientTest.java
netbox-client/provider/src/test/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesTest.java
netbox-client/provider/src/test/resources/badResponse.json [new file with mode: 0644]

index 0a2e4cc..e4b36dd 100755 (executable)
@@ -318,4 +318,6 @@ vpn-binding = /aai/v13/network/vpn-bindings/vpn-binding/{vpn-id}
 vpn-binding|route-targets = /aai/v13/network/vpn-bindings/vpn-binding/{vpn-id}/route-targets
 vpn-binding|route-target = /aai/v13/network/vpn-bindings/vpn-binding/{vpn-id}/route-targets/route-target/{global-route-target}/{route-target-role}
 zones = /aai/v13/network/zones
-zone = /aai/v13/network/zones/zone/{zone-id}
\ No newline at end of file
+zone = /aai/v13/network/zones/zone/{zone-id}
+esr-thirdparty-sdnc = /aai/v11/external-system/esr-thirdparty-sdnc-list/esr-thirdparty-sdnc/{thirdparty-sdnc-id}
+esr-thirdparty-sdnc-list = /aai/v11/external-system/esr-thirdparty-sdnc-list
\ No newline at end of file
index cac2b98..ae5d9a1 100644 (file)
        OF ANY KIND, either express or implied. See the License for the specific 
        language governing permissions and limitations under the License. ECOMP is 
        a trademark and service mark of AT&T Intellectual Property. ============LICENSE_END========================================================= -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
                <groupId>org.onap.ccsdk.parent</groupId>
                <artifactId>binding-parent</artifactId>
                <version>1.1.0-SNAPSHOT</version>
-               <relativePath />
+               <relativePath/>
        </parent>
 
        <groupId>org.onap.ccsdk.sli.adaptors</groupId>
index 871f3bb..64bc260 100644 (file)
                        <type>xml</type>
                        <classifier>features</classifier>
                </dependency>
+               <dependency>
+                       <groupId>${project.groupId}</groupId>
+                       <artifactId>ccsdk-netbox-client</artifactId>
+                       <version>${project.version}</version>
+                       <type>xml</type>
+                       <classifier>features</classifier>
+               </dependency>
                <dependency>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>ccsdk-mdsal-resource</artifactId>
index 2e8680d..04ab0ed 100755 (executable)
@@ -22,7 +22,7 @@
         <groupId>org.onap.ccsdk.parent</groupId>
         <artifactId>odlparent-lite</artifactId>
         <version>1.1.0-SNAPSHOT</version>
-        <relativePath/>
+        <relativePath />
     </parent>
 
     <groupId>org.onap.ccsdk.sli.adaptors</groupId>
     <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name>
 
     <properties>
-        <application.name>sdnc-netbox-client</application.name>
+        <application.name>ccsdk-netbox-client</application.name>
         <features.boot>${application.name}</features.boot>
-        <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features
-        </features.repositories>
+        <features.repositories>mvn:org.onap.ccsdk.sli.adaptors/${features.boot}/${project.version}/xml/features</features.repositories>
         <include.transitive.dependencies>false</include.transitive.dependencies>
     </properties>
 
@@ -61,6 +60,7 @@
             <artifactId>netbox-client-provider</artifactId>
             <version>${project.version}</version>
         </dependency>
+
     </dependencies>
 
     <build>
                         </goals>
                         <phase>package</phase>
                         <configuration>
-                            <attach>false</attach>
+                            <attach>true</attach>
                             <finalName>stage/${application.name}-${project.version}</finalName>
                             <descriptors>
                                 <descriptor>src/assembly/assemble_mvnrepo_zip.xml</descriptor>
                             </descriptors>
-                            <appendAssemblyId>false</appendAssemblyId>
+                            <appendAssemblyId>true</appendAssemblyId>
                         </configuration>
                     </execution>
                     <execution>
                             <useRepositoryLayout>true</useRepositoryLayout>
                             <addParentPoms>false</addParentPoms>
                             <copyPom>false</copyPom>
-                            <excludeGroupIds>org.onap.ccsdk.sli.core,org.opendaylight</excludeGroupIds>
+                            <includeGroupIds>org.onap.ccsdk.sli.adaptors</includeGroupIds>
                             <scope>provided</scope>
                         </configuration>
                     </execution>
index 4950f52..b905cfe 100644 (file)
@@ -20,7 +20,7 @@
   xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.0 http://maven.apache.org/xsd/assembly-1.1.0.xsd">
-    <id>mvnrepo_zip</id>
+    <id>repo</id>
     <formats>
         <format>zip</format>
     </formats>
index 16695f2..e4e2246 100644 (file)
@@ -34,6 +34,7 @@
     <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name>
 
     <dependencies>
+
         <dependency>
             <groupId>com.google.code.gson</groupId>
             <artifactId>gson</artifactId>
         </dependency>
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpclient-osgi</artifactId>
-            <version>${apache.httpcomponents.client.version}</version>
-        </dependency>
-        <dependency>
-            <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpasyncclient-osgi</artifactId>
-            <version>4.1.3</version>
+            <artifactId>httpcore</artifactId>
+            <version>${apache.httpcomponents.core.version}</version>
         </dependency>
         <dependency>
             <groupId>org.apache.httpcomponents</groupId>
-            <artifactId>httpcore-osgi</artifactId>
-            <version>${apache.httpcomponents.core.version}</version>
+            <artifactId>httpclient</artifactId>
+            <version>${apache.httpcomponents.client.version}</version>
         </dependency>
         <dependency>
             <groupId>org.slf4j</groupId>
             <artifactId>sli-common</artifactId>
             <scope>compile</scope>
         </dependency>
+        <dependency>
+            <groupId>org.onap.ccsdk.sli.core</groupId>
+            <artifactId>sliPluginUtils-provider</artifactId>
+            <version>${project.version}</version>
+            <scope>compile</scope>
+        </dependency>
 
         <!--Testing-->
         <dependency>
index 57d727a..f770d15 100644 (file)
  */
 package org.onap.ccsdk.sli.adaptors.netbox.api;
 
-import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress;
-import org.onap.ccsdk.sli.adaptors.netbox.model.Prefix;
+import java.util.Map;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicJavaPlugin;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
 
-public interface NetboxClient {
+/**
+ * This client is meant to interact both with the IPAM system, and the SDNC DB, in order to provide, at any time,
+ * an up to date status of the assigned resources.
+ */
+public interface NetboxClient extends SvcLogicJavaPlugin {
 
     /**
-     * Assign next available IP in prefix.
+     * Assign next available IP in prefix and store it in the SDNC database, table IPAM_IP_ASSIGNEMENT.
      *
-     * @param prefix The prefix from which to get next available IP.
-     * @return The IPAddress
-     * @throws IpamException If something goes wrong.
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     * <tbody>
+     * <tr><td>service_instance_id</td><td>Mandatory</td><td>The service instance ID uniquely identifying the service.</td></tr>
+     * <tr><td>vf_module_id</td><td>Mandatory</td><td>The VF module ID uniquely identifying the VF.</td></tr>
+     * <tr><td>prefix_id</td><td>Mandatory</td><td>The prefix from which to get next available IP.</td></tr>
+     * </tbody>
+     * </table>
      */
-    IPAddress assign(Prefix prefix) throws IpamException;
+    QueryStatus assignIpAddress(Map<String, String> parameters, SvcLogicContext ctx);
 
     /**
-     * Free the IP.
+     * Release the IP and update the entry in the SDNC database, table IPAM_IP_ASSIGNEMENT.
      *
-     * @param ip The IP to release.
-     * @throws IpamException If something goes wrong.
+     * @param parameters HashMap<String,String> of parameters passed by the DG to this function
+     * <table border="1">
+     * <thead><th>parameter</th><th>Mandatory/Optional</th><th>description</th></thead>
+     * <tbody>
+     * <tr><td>service_instance_id</td><td>Mandatory</td><td>The service instance ID uniquely identifying the service.</td></tr>
+     * <tr><td>vf_module_id</td><td>Mandatory</td><td>The VF module ID uniquely identifying the VF.</td></tr>
+     * <tr><td>ip_address_id</td><td>Mandatory</td><td>The IP to release.</td></tr>
+     * </tbody>
+     * </table>
      */
-    void unassign(IPAddress ip) throws IpamException;
+    QueryStatus unassignIpAddress(Map<String, String> parameters, SvcLogicContext ctx);
 }
 
index 0520ad5..b54a35b 100644 (file)
  */
 package org.onap.ccsdk.sli.adaptors.netbox.impl;
 
-import com.google.common.annotations.VisibleForTesting;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
-import com.google.gson.JsonSerializer;
+import com.google.common.collect.Lists;
+import com.google.gson.JsonSyntaxException;
 import java.io.IOException;
-import java.io.InputStreamReader;
-import java.io.Reader;
-import java.util.concurrent.CompletionException;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Map;
+import javax.sql.rowset.CachedRowSet;
 import org.apache.http.HttpResponse;
-import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
+import org.apache.http.util.EntityUtils;
 import org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient;
 import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress;
-import org.onap.ccsdk.sli.adaptors.netbox.model.Prefix;
-import org.onap.ccsdk.sli.adaptors.netbox.model.Status;
+import org.onap.ccsdk.sli.adaptors.netbox.model.IPStatus;
+import org.onap.ccsdk.sli.core.dblib.DbLibService;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicException;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
+import org.onap.ccsdk.sli.core.slipluginutils.SliPluginUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class NetboxClientImpl implements NetboxClient {
 
+    private static final Logger LOG = LoggerFactory.getLogger(NetboxClientImpl.class);
+
+    // Netbox URI
+
     private static final String NEXT_AVAILABLE_IP_IN_PREFIX_PATH = "/api/ipam/prefixes/%s/available-ips/";
     private static final String IP_ADDRESS_PATH = "/api/ipam/ip-addresses/%s/";
-    private static final String EMPTY_STRING = "";
-    private static final String ID_MISSING_MSG = "Id must be set";
+
+    // Netbox Payload
+
+    private static final String ASSIGN_IP_ADDRESS_PAYLOAD = "{\n"
+        + "  \"custom_fields\": {\n"
+        + "    \"external-key\": \"%s\",\n"
+        + "    \"resource-name\": \"%s\"\n"
+        + "  }\n"
+        + "}";
+
+    // Service Logic Context input variables and exception
+
+    private static final String SERVICE_INSTANCE_ID_PROP = "service_instance_id";
+    private static final String VF_MODULE_ID_PROP = "vf_module_id";
+    private static final String EXTERNAL_KEY_PROP = "external_key";
+    private static final String SQL_EXCEPTION_MESSAGE = "Caught SQL exception";
+
+    // SQL statement
+
+    private static final String ASSIGN_IP_SQL_STATEMENT =
+        "INSERT INTO IPAM_IP_ASSIGNEMENT (service_instance_id, vf_module_id, prefix_id, ip_address_id, ip_address, ip_status, ip_response_json, external_key) \n"
+            + "VALUES (?, ?, ?, ?, ?, ?, ?, ?)";
+    private static final String UNASSIGN_IP_SQL_STATEMENT =
+        "UPDATE IPAM_IP_ASSIGNEMENT SET ip_status = ? WHERE service_instance_id = ? AND external_key = ?";
+    private static final String GET_IP_ADDRESS_ID_SQL_STATEMENT =
+        "SELECT ip_address_id FROM IPAM_IP_ASSIGNEMENT WHERE service_instance_id = ? AND external_key = ?";
 
     private final NetboxHttpClient client;
-    private final Gson gson;
+    private final DbLibService dbLibService;
 
-    public NetboxClientImpl(final NetboxHttpClient client) {
+    public NetboxClientImpl(final NetboxHttpClient client, final DbLibService dbLibService) {
         this.client = client;
-        final JsonSerializer<Status> vlanStatusDeserializer = (val, type, context) -> val.toJson();
-        gson = new GsonBuilder()
-            .registerTypeAdapter(Status.class, vlanStatusDeserializer)
-            .create();
+        this.dbLibService = dbLibService;
     }
 
     @Override
-    public IPAddress assign(final Prefix prefix) throws IpamException {
-        checkArgument(prefix.getId() != null);
+    public QueryStatus assignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) {
+
         try {
-            return client.post(String.format(NEXT_AVAILABLE_IP_IN_PREFIX_PATH, prefix.getId()), EMPTY_STRING)
-                .thenApply(this::getIpAddress)
-                .toCompletableFuture()
-                .join();
-        } catch (CompletionException e) {
-            // Unwrap the ComplettionException and wrap in IpamException
-            throw new IpamException("Fail to assign IP for Prefix(id= " + prefix.getId() + "). " + e.getMessage(),
-                e.getCause());
+            SliPluginUtils
+                .checkParameters(parameters,
+                    new String[]{SERVICE_INSTANCE_ID_PROP, VF_MODULE_ID_PROP, "prefix_id", "resource_name",
+                        EXTERNAL_KEY_PROP}, LOG);
+        } catch (SvcLogicException e) {
+            return QueryStatus.FAILURE;
         }
+
+        final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP);
+        final String vfModuleId = parameters.get(VF_MODULE_ID_PROP);
+        final String prefixId = parameters.get("prefix_id");
+        final String resourceName = parameters.get("resource_name");
+        final String externalKey = parameters.get(EXTERNAL_KEY_PROP);
+
+        HttpResponse httpResp;
+        try {
+            httpResp = client
+                .post(String.format(NEXT_AVAILABLE_IP_IN_PREFIX_PATH, prefixId),
+                    String.format(ASSIGN_IP_ADDRESS_PAYLOAD, externalKey, resourceName));
+        } catch (IOException e) {
+            LOG.error("Fail to assign IP for Prefix(id={}). {}", prefixId, e.getMessage(), e.getCause());
+            return QueryStatus.FAILURE;
+        }
+
+        String ipamRespJson;
+        try {
+            ipamRespJson = EntityUtils.toString(httpResp.getEntity(), "UTF-8");
+        } catch (IOException e) {
+            LOG.error("Fail to parse IPAM response for assign in Prefix(id={}). Response={}", prefixId,
+                httpResp.getEntity(), e);
+            return QueryStatus.FAILURE;
+        }
+
+        if (httpResp.getStatusLine().getStatusCode() != 201) {
+            LOG.error("Fail to assign IP for Prefix(id={}). HTTP code 201!={}. Response={}", prefixId,
+                httpResp.getStatusLine().getStatusCode(), ipamRespJson);
+            return QueryStatus.FAILURE;
+        }
+
+        IPAddress ipAddress;
+        try {
+            ipAddress = IPAddress.fromJson(ipamRespJson);
+        } catch (JsonSyntaxException e) {
+            LOG.error("Fail to parse IPAM JSON reponse to IPAddress POJO. IPAM JSON Response={}", ipamRespJson, e);
+            return QueryStatus.FAILURE;
+        }
+
+        ArrayList<String> args = Lists.newArrayList(
+            serviceInstanceId,
+            vfModuleId,
+            String.valueOf(prefixId),
+            String.valueOf(ipAddress.getId()),
+            ipAddress.getAddress(),
+            IPStatus.ASSIGNED.name(),
+            ipamRespJson,
+            externalKey);
+
+        try {
+            dbLibService.writeData(ASSIGN_IP_SQL_STATEMENT, args, null);
+        } catch (SQLException e) {
+            LOG.error(SQL_EXCEPTION_MESSAGE, e);
+            return QueryStatus.FAILURE;
+        }
+
+        ctx.setAttribute("self_serve_netbox_ip_assignement.ip-address", ipAddress.getAddress());
+
+        return QueryStatus.SUCCESS;
     }
 
     @Override
-    public void unassign(final IPAddress ipAddress) throws IpamException {
-        checkArgument(ipAddress.getId() != null);
+    public QueryStatus unassignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) {
         try {
-            client.delete(String.format(IP_ADDRESS_PATH, ipAddress.getId()))
-                .thenAccept(this::checkResult)
-                .toCompletableFuture()
-                .join();
-        } catch (CompletionException e) {
-            // Unwrap the ComplettionException and wrap in IpamException
-            throw new IpamException("Fail to unassign IP for IPAddress(id= " + ipAddress.getId() + "). " + e.getMessage(),
-                e.getCause());
+            SliPluginUtils
+                .checkParameters(parameters, new String[]{SERVICE_INSTANCE_ID_PROP, EXTERNAL_KEY_PROP},
+                    LOG);
+        } catch (SvcLogicException e) {
+            return QueryStatus.FAILURE;
         }
-    }
 
-    @VisibleForTesting
-    IPAddress getIpAddress(final HttpResponse response) {
-        if (response.getStatusLine().getStatusCode() != 201) {
-            throw new IllegalStateException(NetboxHttpClient.getBodyAsString(response));
+        final String serviceInstanceId = parameters.get(SERVICE_INSTANCE_ID_PROP);
+        final String externalKey = parameters.get(EXTERNAL_KEY_PROP);
+
+        String ipAddressId;
+        ArrayList<String> args = Lists.newArrayList(
+            serviceInstanceId,
+            externalKey);
+        try (CachedRowSet row = dbLibService.getData(GET_IP_ADDRESS_ID_SQL_STATEMENT, args, null)) {
+            if (row.next()) {
+                ipAddressId = row.getString("ip_address_id");
+            } else {
+                throw new SQLException("Data not found.");
+            }
+        } catch (SQLException e) {
+            LOG.error(SQL_EXCEPTION_MESSAGE, e);
+            return QueryStatus.FAILURE;
         }
-        try (final Reader reader = new InputStreamReader(response.getEntity().getContent())) {
-            return gson.fromJson(reader, IPAddress.class);
-        } catch (final IOException e) {
-            throw new IllegalStateException(e);
+
+        HttpResponse httpResp;
+        try {
+            httpResp = client.delete(String.format(IP_ADDRESS_PATH, ipAddressId));
+        } catch (IOException e) {
+            LOG.error("Fail to unassign IP for IPAddress(id= " + ipAddressId + "). " + e.getMessage(),
+                e.getCause());
+            return QueryStatus.FAILURE;
         }
-    }
 
-    private static void checkArgument(final boolean argument) throws IpamException {
-        if (!argument) {
-            throw new IpamException(ID_MISSING_MSG);
+        if (httpResp.getStatusLine().getStatusCode() - 200 >= 100) {
+            LOG.error("Fail to unassign IP for IPAddress(id={}). HTTP code={}.", ipAddressId,
+                httpResp.getStatusLine().getStatusCode());
+            return QueryStatus.FAILURE;
         }
-    }
 
-    private void checkResult(final HttpResponse response) {
-        if (response.getStatusLine().getStatusCode() - 200 >= 100) {
-            throw new IllegalStateException(
-                "Netbox request failed with status: " + NetboxHttpClient.getBodyAsString(response));
+        args.clear();
+        args = Lists.newArrayList(
+            IPStatus.DELETED.name(),
+            serviceInstanceId,
+            externalKey);
+
+        try {
+            dbLibService.writeData(UNASSIGN_IP_SQL_STATEMENT, args, null);
+        } catch (SQLException e) {
+            LOG.error(SQL_EXCEPTION_MESSAGE, e);
+            return QueryStatus.FAILURE;
         }
+
+        return QueryStatus.SUCCESS;
     }
 }
index a77b4d3..505c5a7 100644 (file)
@@ -24,31 +24,24 @@ import java.nio.charset.Charset;
 import java.security.KeyManagementException;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
-import java.util.Scanner;
-import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.CompletionStage;
-import java.util.function.Function;
 import javax.net.ssl.SSLContext;
-import org.apache.http.HttpEntityEnclosingRequest;
 import org.apache.http.HttpResponse;
 import org.apache.http.client.methods.HttpDelete;
 import org.apache.http.client.methods.HttpPost;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.concurrent.FutureCallback;
+import org.apache.http.client.methods.HttpRequestBase;
 import org.apache.http.conn.ssl.NoopHostnameVerifier;
 import org.apache.http.entity.StringEntity;
-import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
-import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClientBuilder;
 import org.apache.http.ssl.SSLContexts;
 import org.apache.http.ssl.TrustStrategy;
-import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
 import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties;
 
 public class NetboxHttpClient implements AutoCloseable {
 
     private static final String APPLICATION_JSON = "application/json";
 
-    private final CloseableHttpAsyncClient client;
+    private final CloseableHttpClient client;
     private final String url;
     private final String token;
 
@@ -69,16 +62,10 @@ public class NetboxHttpClient implements AutoCloseable {
         } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
             throw new IllegalStateException("Can't create http client", e);
         }
-        client = HttpAsyncClientBuilder.create()
+        client = HttpClientBuilder.create()
             .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
             .setSSLContext(sslContext)
             .build();
-
-    }
-
-    // Has to be public for blueprint container to access it
-    public void init() {
-        client.start();
     }
 
     @Override
@@ -86,66 +73,22 @@ public class NetboxHttpClient implements AutoCloseable {
         client.close();
     }
 
-    CompletionStage<HttpResponse> post(final String uri, final String requestBody) {
-        return sendRequest(uri, requestBody, HttpPost::new);
-    }
-
-    CompletionStage<HttpResponse> delete(final String uri) {
-        return sendRequest(uri, HttpDelete::new);
+    HttpResponse post(final String uri, final String requestBody) throws IOException {
+        final HttpPost request = new HttpPost(url + uri);
+        setHeaders(request);
+        request.setEntity(new StringEntity(requestBody, Charset.forName("UTF-8")));
+        return client.execute(request);
     }
 
-    static String getBodyAsString(final HttpResponse response) {
-        final String body;
-        if (response.getEntity() != null) {
-            try (final Scanner s = new java.util.Scanner(response.getEntity().getContent()).useDelimiter("\\A")) {
-                body = s.hasNext() ? s.next() : "";
-            } catch (final IOException e) {
-                throw new IllegalStateException(e);
-            }
-        } else {
-            body = "";
-        }
-        return response.toString() + "\n" + body;
+    HttpResponse delete(final String uri) throws IOException {
+        final HttpDelete request = new HttpDelete(url + uri);
+        setHeaders(request);
+        return client.execute(request);
     }
 
-    private <T extends HttpUriRequest> CompletionStage<HttpResponse> sendRequest(final String uri,
-        final Function<String, T> supplier) {
-        final T request = supplier.apply(url + uri);
+    private void setHeaders(final HttpRequestBase request) {
         request.addHeader(ACCEPT, APPLICATION_JSON);
         request.addHeader(CONTENT_TYPE, APPLICATION_JSON);
         request.addHeader(AUTHORIZATION, "Token " + token);
-        return sendRequest(request);
-    }
-
-    private <T extends HttpEntityEnclosingRequest & HttpUriRequest>
-    CompletionStage<HttpResponse> sendRequest(final String uri, final String body,
-        final Function<String, T> supplier) {
-        final T request = supplier.apply(url + uri);
-        request.addHeader(ACCEPT, APPLICATION_JSON);
-        request.addHeader(CONTENT_TYPE, APPLICATION_JSON);
-        request.addHeader(AUTHORIZATION, "Token " + token);
-        request.setEntity(new StringEntity(body, Charset.forName("UTF-8")));
-        return sendRequest(request);
-    }
-
-    private CompletionStage<HttpResponse> sendRequest(final HttpUriRequest request) {
-        final CompletableFuture<HttpResponse> future = new CompletableFuture<>();
-        client.execute(request, new FutureCallback<HttpResponse>() {
-            @Override
-            public void completed(final HttpResponse httpResponse) {
-                future.complete(httpResponse);
-            }
-
-            @Override
-            public void failed(final Exception e) {
-                future.completeExceptionally(new IpamException("Netbox request failed", e));
-            }
-
-            @Override
-            public void cancelled() {
-                future.cancel(false);
-            }
-        });
-        return future;
     }
 }
\ No newline at end of file
index 6d62fff..4c2880b 100644 (file)
  */
 package org.onap.ccsdk.sli.adaptors.netbox.model;
 
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
 import java.util.Objects;
 
 public class IPAddress extends Identifiable {
 
-    private Status.Values status;
-    private String address;
+    private static final Gson gson = new GsonBuilder().create();
 
-    public void setStatus(Status.Values status) {
-        this.status = status;
-    }
+    private String address;
 
     public void setAddress(String address) {
         this.address = address;
     }
 
-    public Status.Values getStatus() {
-        return status;
-    }
-
     public String getAddress() {
         return address;
     }
@@ -47,12 +42,15 @@ public class IPAddress extends Identifiable {
             return false;
         }
         IPAddress ipAddress = (IPAddress) o;
-        return Objects.equals(status, ipAddress.status) &&
-            Objects.equals(address, ipAddress.address);
+        return Objects.equals(address, ipAddress.address);
     }
 
     @Override
     public int hashCode() {
-        return Objects.hash(status, address);
+        return Objects.hash(address);
+    }
+
+    public static IPAddress fromJson(final String json) {
+        return gson.fromJson(json, IPAddress.class);
     }
 }
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPStatus.java
new file mode 100644 (file)
index 0000000..f3a7438
--- /dev/null
@@ -0,0 +1,5 @@
+package org.onap.ccsdk.sli.adaptors.netbox.model;
+
+public enum IPStatus {
+    ASSIGNED, DELETED
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Status.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Status.java
deleted file mode 100644 (file)
index c56828a..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2018 Bell Canada.
- *
- * 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.ccsdk.sli.adaptors.netbox.model;
-
-import com.google.gson.JsonElement;
-import com.google.gson.JsonPrimitive;
-import com.google.gson.annotations.SerializedName;
-
-public class Status {
-
-    private Integer value;
-    private String label;
-
-    public Integer getValue() {
-        return value;
-    }
-
-    public void setValue(final Integer value) {
-        this.value = value;
-    }
-
-    public String getLabel() {
-        return label;
-    }
-
-    public void setLabel(final String label) {
-        this.label = label;
-    }
-
-    public JsonElement toJson() {
-        return new JsonPrimitive(value);
-    }
-
-    public enum Values {
-        @SerializedName("1")
-        ACTIVE(1, "Active"),
-        @SerializedName("2")
-        RESERVED(2, "Reserved");
-
-        private final int value;
-        private final String label;
-
-        Values(final int value, final String label) {
-            this.value = value;
-            this.label = label;
-        }
-
-        public int getValue() {
-            return value;
-        }
-
-        public String getLabel() {
-            return label;
-        }
-
-        public Status getStatus() {
-            final Status status = new Status();
-            status.setValue(value);
-            status.setLabel(label);
-            return status;
-        }
-
-    }
-}
index cf8a1af..b667dcb 100644 (file)
 <blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0" xmlns:odl="http://opendaylight.org/xmlns/blueprint/v1.0.0"
   odl:use-default-for-reference-types="true">
 
+    <reference id="dbLibService"
+      interface="org.onap.ccsdk.sli.core.dblib.DbLibService"/>
+
     <bean id="netboxProperty" class="org.onap.ccsdk.sli.adaptors.netbox.property.NetboxProperties"/>
-    <bean id="httpClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClient" init-method="init"
-      destroy-method="close">
+    <bean id="httpClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClient" destroy-method="close">
         <argument ref="netboxProperty"/>
     </bean>
 
     <bean id="netboxClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImpl">
         <argument ref="httpClient"/>
+        <argument ref="dbLibService"/>
     </bean>
 
     <service ref="netboxClient"
index 19b178c..624a190 100644 (file)
@@ -20,7 +20,6 @@ import static com.github.tomakehurst.wiremock.client.WireMock.delete;
 import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
 import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
 import static com.github.tomakehurst.wiremock.client.WireMock.givenThat;
-import static com.github.tomakehurst.wiremock.client.WireMock.ok;
 import static com.github.tomakehurst.wiremock.client.WireMock.post;
 import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
 import static com.github.tomakehurst.wiremock.client.WireMock.serverError;
@@ -30,31 +29,43 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMoc
 import static org.apache.http.HttpHeaders.ACCEPT;
 import static org.apache.http.HttpHeaders.AUTHORIZATION;
 import static org.apache.http.HttpHeaders.CONTENT_TYPE;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
 
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
 import com.github.tomakehurst.wiremock.junit.WireMockRule;
 import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
 import com.google.common.io.Resources;
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.InputStream;
 import java.net.URL;
-import java.nio.charset.StandardCharsets;
-import org.apache.http.HttpEntity;
-import org.apache.http.HttpResponse;
-import org.apache.http.StatusLine;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import javax.sql.rowset.CachedRowSet;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
 import org.mockito.runners.MockitoJUnitRunner;
-import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
-import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress;
-import org.onap.ccsdk.sli.adaptors.netbox.model.Prefix;
-import org.onap.ccsdk.sli.adaptors.netbox.model.Status.Values;
+import org.onap.ccsdk.sli.core.dblib.DbLibService;
+import org.onap.ccsdk.sli.core.sli.SvcLogicContext;
+import org.onap.ccsdk.sli.core.sli.SvcLogicResource.QueryStatus;
+import org.slf4j.LoggerFactory;
 
 @RunWith(MockitoJUnitRunner.class)
 public class NetboxClientImplTest {
@@ -63,20 +74,50 @@ public class NetboxClientImplTest {
 
     @Rule
     public WireMockRule wm = new WireMockRule(wireMockConfig().dynamicPort());
+    @Mock
+    private DbLibService dbLib;
+    @Mock
+    private SvcLogicContext svcLogicContext;
+    @Mock
+    private Appender<ILoggingEvent> appender;
+    @Captor
+    private ArgumentCaptor<ILoggingEvent> captor;
+
 
     private String token = "token";
+    private String serviceInstanceId = UUID.randomUUID().toString();
+    private String vfModuleId = UUID.randomUUID().toString();
+
+    private Map<String, String> params = ImmutableMap
+        .of("service_instance_id", serviceInstanceId,
+            "vf_module_id", vfModuleId,
+            "prefix_id", "3",
+            "external_key", "3",
+            "resource_name", "3"
+        );
 
     private NetboxHttpClient httpClient;
     private NetboxClientImpl netboxClient;
 
+    @Mock
+    private NetboxHttpClient httpClientMock;
+    @Mock
+    private NetboxClientImpl netboxClientMock;
+
+
     @Before
     public void setup() {
+        ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory
+            .getLogger(NetboxClientImpl.class);
+        logger.addAppender(appender);
+
         String baseUrl = "http://localhost:" + wm.port();
 
         httpClient = new NetboxHttpClient(baseUrl, token);
-        httpClient.init();
 
-        netboxClient = new NetboxClientImpl(httpClient);
+        netboxClient = new NetboxClientImpl(httpClient, dbLib);
+
+        netboxClientMock = new NetboxClientImpl(httpClientMock, dbLib);
 
         wm.addMockServiceRequestListener(
             (request, response) -> {
@@ -93,93 +134,180 @@ public class NetboxClientImplTest {
     }
 
     @Test
-    public void nextAvailableIpInPrefixTestNoId() {
-        Prefix prefix = mock(Prefix.class);
-        doReturn(null).when(prefix).getId();
-        try {
-            netboxClient.assign(prefix);
-        } catch (IpamException e) {
-            Assert.assertEquals("Id must be set", e.getMessage());
-            return;
-        }
-        Assert.fail();
+    public void unassignIpAddressTestNoParams() {
+        QueryStatus status = netboxClient.unassignIpAddress(ImmutableMap.of(), svcLogicContext);
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry(
+            "This method requires the parameters [service_instance_id,external_key], but no parameters were passed in.");
     }
 
     @Test
-    public void nextAvailableIpInPrefixTest() throws IOException, IpamException {
-        Integer id = 3;
-        Prefix prefix = mock(Prefix.class);
-        doReturn(id).when(prefix).getId();
+    public void unassignIpAddressFailedRequest() throws IOException, SQLException {
+        doThrow(new IOException("Failed request")).when(httpClientMock).delete(anyString());
 
-        URL url = Resources.getResource("nextAvailableIpResponse.json");
-        String response = Resources.toString(url, Charsets.UTF_8);
+        CachedRowSet crs = mock(CachedRowSet.class);
+        doReturn("3").when(crs).getString(eq("ip_address_id"));
+        doReturn(true).when(crs).next();
+        doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null));
 
-        String expectedUrl = "/api/ipam/prefixes/" + id + "/available-ips/";
-        givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
-
-        netboxClient.assign(prefix);
+        QueryStatus status = netboxClientMock
+            .unassignIpAddress(params, svcLogicContext);
 
-        verify(postRequestedFor(urlEqualTo(expectedUrl))
-            .withHeader(ACCEPT, equalTo(APPLICATION_JSON))
-            .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON))
-            .withHeader(AUTHORIZATION, equalTo("Token " + token)));
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Fail to unassign IP for IPAddress(id= 3). Failed request");
     }
 
     @Test
-    public void deleteIpTestError500() {
-        Integer id = 3;
-        IPAddress ipAddress = mock(IPAddress.class);
-        doReturn(id).when(ipAddress).getId();
+    public void unassignIpAddressServerError() throws SQLException {
 
-        String expectedUrl = "/api/ipam/ip-addresses/" + id + "/";
+        String expectedUrl = "/api/ipam/ip-addresses/3/";
         givenThat(delete(urlEqualTo(expectedUrl)).willReturn(serverError()));
-        try {
-            netboxClient.unassign(ipAddress);
-        } catch (IpamException e) {
-            Assert.assertEquals(IllegalStateException.class, e.getCause().getClass());
-            Assert.assertTrue(e.getMessage().contains(
-                "Fail to unassign IP for IPAddress(id= 3). java.lang.IllegalStateException: Netbox request failed with status: HTTP/1.1 500 Server Error"));
-            return;
-        }
-        Assert.fail();
+
+        CachedRowSet crs = mock(CachedRowSet.class);
+        doReturn("3").when(crs).getString(eq("ip_address_id"));
+        doReturn(true).when(crs).next();
+        doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null));
+
+        QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Fail to unassign IP for IPAddress(id=3). HTTP code=500.");
+    }
+
+    @Test
+    public void unassignIpAddressFailSQL() throws IOException, SQLException {
+
+        String response = "{}";
+
+        String expectedUrl = "/api/ipam/ip-addresses/3/";
+        givenThat(delete(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
+
+        CachedRowSet crs = mock(CachedRowSet.class);
+        doReturn(true).when(crs).next();
+        doReturn("3").when(crs).getString(eq("ip_address_id"));
+        doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null));
+
+        doThrow(new SQLException("Failed")).when(dbLib).writeData(anyString(), any(ArrayList.class), eq(null));
+
+        QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Caught SQL exception");
     }
 
     @Test
-    public void deleteIpTest() throws IpamException {
-        Integer id = 3;
-        IPAddress ipAddress = mock(IPAddress.class);
-        doReturn(id).when(ipAddress).getId();
-
-        String expectedUrl = "/api/ipam/ip-addresses/" + id + "/";
-        givenThat(delete(urlEqualTo(expectedUrl)).willReturn(ok()));
-        netboxClient.unassign(ipAddress);
+    public void unassignIpAddressSuccess() throws IOException, SQLException {
+        String response = "{}";
+
+        String expectedUrl = "/api/ipam/ip-addresses/3/";
+        givenThat(delete(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
+
+        CachedRowSet crs = mock(CachedRowSet.class);
+        doReturn("3").when(crs).getString(eq("ip_address_id"));
+        doReturn(true).when(crs).next();
+        doReturn(crs).when(dbLib).getData(anyString(), any(ArrayList.class), eq(null));
+
+        QueryStatus status = netboxClient.unassignIpAddress(params, svcLogicContext);
+
         verify(deleteRequestedFor(urlEqualTo(expectedUrl))
             .withHeader(ACCEPT, equalTo(APPLICATION_JSON))
             .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON))
             .withHeader(AUTHORIZATION, equalTo("Token " + token)));
+
+        Mockito.verify(dbLib).writeData(anyString(), any(ArrayList.class), eq(null));
+        Assert.assertEquals(QueryStatus.SUCCESS, status);
+    }
+
+
+    @Test
+    public void nextAvailableIpInPrefixTestNoId() {
+        QueryStatus status = netboxClient.assignIpAddress(ImmutableMap.of(), svcLogicContext);
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry(
+            "This method requires the parameters [service_instance_id,vf_module_id,prefix_id,resource_name,external_key], but no parameters were passed in.");
+    }
+
+    @Test
+    public void nextAvailableIpInPrefixFailedRequest() throws IOException {
+        doThrow(new IOException("Failed request")).when(httpClientMock).post(anyString(), anyString());
+        QueryStatus status = netboxClientMock.assignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Fail to assign IP for Prefix(id=3). Failed request");
     }
 
+    @Test
+    public void nextAvailableIpInPrefixBadRespPayload() throws IOException {
+        URL url = Resources.getResource("badResponse.json");
+        String response = Resources.toString(url, Charsets.UTF_8);
+
+        String expectedUrl = "/api/ipam/prefixes/3/available-ips/";
+        givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
+
+        QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Fail to parse IPAM JSON reponse to IPAddress POJO. IPAM JSON Response={\n"
+            + "  \"id\": 8\n"
+            + "  \"address\": \"192.168.20.7/32\"\n"
+            + "}");
+    }
+
+    @Test
+    public void nextAvailableIpInPrefixFailSQL() throws IOException, SQLException {
+        URL url = Resources.getResource("nextAvailableIpResponse.json");
+        String response = Resources.toString(url, Charsets.UTF_8);
+
+        String expectedUrl = "/api/ipam/prefixes/3/available-ips/";
+        givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
+
+        doThrow(new SQLException("Failed")).when(dbLib).writeData(anyString(), any(ArrayList.class), eq(null));
+
+        QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Caught SQL exception");
+    }
 
     @Test
-    public void getIpAddressTest() throws IOException {
-        StatusLine statusLine = mock(StatusLine.class);
-        doReturn(201).when(statusLine).getStatusCode();
+    public void nextAvailableIpInPrefixError500() throws IOException {
+        URL url = Resources.getResource("nextAvailableIpResponse.json");
+        String response = Resources.toString(url, Charsets.UTF_8);
 
+        String expectedUrl = "/api/ipam/prefixes/3/available-ips/";
+        givenThat(post(urlEqualTo(expectedUrl)).willReturn(serverError().withBody(response)));
+
+        QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext);
+
+        Assert.assertEquals(QueryStatus.FAILURE, status);
+        verifyLogEntry("Fail to assign IP for Prefix(id=3). HTTP code 201!=500.");
+    }
+
+    @Test
+    public void nextAvailableIpInPrefixSuccess() throws IOException, SQLException {
         URL url = Resources.getResource("nextAvailableIpResponse.json");
         String response = Resources.toString(url, Charsets.UTF_8);
-        InputStream stream = new ByteArrayInputStream(response.getBytes(StandardCharsets.UTF_8));
 
-        HttpEntity entity = mock(HttpEntity.class);
-        doReturn(stream).when(entity).getContent();
+        String expectedUrl = "/api/ipam/prefixes/3/available-ips/";
+        givenThat(post(urlEqualTo(expectedUrl)).willReturn(created().withBody(response)));
 
-        HttpResponse httpResponse = mock(HttpResponse.class);
-        doReturn(statusLine).when(httpResponse).getStatusLine();
-        doReturn(entity).when(httpResponse).getEntity();
+        QueryStatus status = netboxClient.assignIpAddress(params, svcLogicContext);
 
-        IPAddress ipAddress = netboxClient.getIpAddress(httpResponse);
+        verify(postRequestedFor(urlEqualTo(expectedUrl))
+            .withHeader(ACCEPT, equalTo(APPLICATION_JSON))
+            .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON))
+            .withHeader(AUTHORIZATION, equalTo("Token " + token)));
 
-        Assert.assertEquals("192.168.20.7/32", ipAddress.getAddress());
-        Assert.assertEquals(Integer.valueOf(8), ipAddress.getId());
-        Assert.assertEquals(Values.ACTIVE, ipAddress.getStatus());
+        Mockito.verify(dbLib).writeData(anyString(), any(ArrayList.class), eq(null));
+        Assert.assertEquals(QueryStatus.SUCCESS, status);
     }
+
+    private void verifyLogEntry(String message) {
+        Mockito.verify(appender, times(1)).doAppend(captor.capture());
+        List<ILoggingEvent> allValues = captor.getAllValues();
+        for (ILoggingEvent loggingEvent : allValues) {
+            Assert.assertTrue(loggingEvent.getFormattedMessage().contains(message));
+        }
+    }
+
 }
\ No newline at end of file
index ee2861c..8634742 100644 (file)
@@ -15,7 +15,6 @@
  */
 package org.onap.ccsdk.sli.adaptors.netbox.impl;
 
-import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
 import static com.github.tomakehurst.wiremock.client.WireMock.delete;
 import static com.github.tomakehurst.wiremock.client.WireMock.deleteRequestedFor;
 import static com.github.tomakehurst.wiremock.client.WireMock.equalTo;
@@ -29,16 +28,12 @@ import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMoc
 import static org.apache.http.HttpHeaders.ACCEPT;
 import static org.apache.http.HttpHeaders.CONTENT_TYPE;
 
-import com.github.tomakehurst.wiremock.http.Fault;
 import com.github.tomakehurst.wiremock.junit.WireMockRule;
 import java.io.IOException;
-import java.util.concurrent.CompletionException;
 import org.junit.After;
-import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
-import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
 
 public class NetboxHttpClientTest {
 
@@ -55,7 +50,6 @@ public class NetboxHttpClientTest {
         String token = "token";
 
         httpClient = new NetboxHttpClient(baseUrl, token);
-        httpClient.init();
 
         wm.addMockServiceRequestListener(
             (request, response) -> {
@@ -72,11 +66,11 @@ public class NetboxHttpClientTest {
     }
 
     @Test
-    public void postTest() {
+    public void postTest() throws IOException {
         String expectedUrl = "/testPost";
         givenThat(post(urlEqualTo(expectedUrl)).willReturn(ok()));
 
-        httpClient.post(expectedUrl, "").toCompletableFuture().join();
+        httpClient.post(expectedUrl, "");
 
         verify(postRequestedFor(urlEqualTo(expectedUrl))
             .withHeader(ACCEPT, equalTo(APPLICATION_JSON))
@@ -84,44 +78,12 @@ public class NetboxHttpClientTest {
     }
 
     @Test
-    public void postTestException() {
-        String expectedUrl = "/testPost";
-        givenThat(post(urlEqualTo(expectedUrl)).willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
-
-        try {
-            httpClient.post(expectedUrl, "").toCompletableFuture().join();
-        } catch (CompletionException e) {
-            Assert.assertEquals(IpamException.class, e.getCause().getClass());
-            Assert.assertEquals("Netbox request failed", e.getCause().getMessage());
-            return;
-        }
-        Assert.fail();
-    }
-
-    @Test
-    public void deleteTest() {
+    public void deleteTest() throws IOException {
         String expectedUrl = "/testDelete";
         givenThat(delete(urlEqualTo(expectedUrl)).willReturn(ok()));
-
-        httpClient.delete(expectedUrl).toCompletableFuture().join();
-
+        httpClient.delete(expectedUrl);
         verify(deleteRequestedFor(urlEqualTo(expectedUrl))
             .withHeader(ACCEPT, equalTo(APPLICATION_JSON))
             .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON)));
     }
-
-    @Test
-    public void deleteTestException() {
-        String expectedUrl = "/testDelete";
-        givenThat(delete(urlEqualTo(expectedUrl)).willReturn(aResponse().withFault(Fault.MALFORMED_RESPONSE_CHUNK)));
-
-        try {
-            httpClient.delete(expectedUrl).toCompletableFuture().join();
-        } catch (CompletionException e) {
-            Assert.assertEquals(IpamException.class, e.getCause().getClass());
-            Assert.assertEquals("Netbox request failed", e.getCause().getMessage());
-            return;
-        }
-        Assert.fail();
-    }
 }
index d991670..be5aabf 100644 (file)
@@ -56,7 +56,6 @@ public class NetboxPropertiesTest {
             "Missing configuration properties resource for Netbox: netbox.properties");
     }
 
-
     private void verifyLogEntry(String message) {
         verify(appender, times(1)).doAppend(captor.capture());
         List<ILoggingEvent> allValues = captor.getAllValues();
diff --git a/netbox-client/provider/src/test/resources/badResponse.json b/netbox-client/provider/src/test/resources/badResponse.json
new file mode 100644 (file)
index 0000000..713109f
--- /dev/null
@@ -0,0 +1,4 @@
+{
+  "id": 8
+  "address": "192.168.20.7/32"
+}
\ No newline at end of file