summaryrefslogtreecommitdiffstats
path: root/netbox-client/provider/src/main
diff options
context:
space:
mode:
authorAlexis de Talhouët <adetalhouet89@gmail.com>2018-08-15 14:30:43 -0400
committerDan Timoney <dt5972@att.com>2018-08-23 15:07:07 +0000
commiteae6b96f6529e4a9f350809a5def4d82a904501b (patch)
tree84a4310a211e01b7c70c674f6441a6632ec7e78d /netbox-client/provider/src/main
parentd2dd55d20da25862545a827cce6cd8f0071a4f99 (diff)
Added netbox client to assign/unassign ip
Change-Id: Ied317c7f251936ced116b6a3ea81789c82095df6 Issue-ID: CCSDK-462 Signed-off-by: Alexis de Talhouët <adetalhouet89@gmail.com>
Diffstat (limited to 'netbox-client/provider/src/main')
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java27
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java40
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java105
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java151
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java58
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java29
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java20
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Status.java77
-rw-r--r--netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java116
-rwxr-xr-xnetbox-client/provider/src/main/resources/netbox.properties19
-rw-r--r--netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml34
11 files changed, 676 insertions, 0 deletions
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java
new file mode 100644
index 000000000..869a57cef
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/IpamException.java
@@ -0,0 +1,27 @@
+/*
+ * 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.api;
+
+public class IpamException extends Exception {
+
+ public IpamException(final String message) {
+ super(message);
+ }
+
+ public IpamException(final String message, final Throwable cause) {
+ super(message, cause);
+ }
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java
new file mode 100644
index 000000000..57d727add
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/api/NetboxClient.java
@@ -0,0 +1,40 @@
+/*
+ * 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.api;
+
+import org.onap.ccsdk.sli.adaptors.netbox.model.IPAddress;
+import org.onap.ccsdk.sli.adaptors.netbox.model.Prefix;
+
+public interface NetboxClient {
+
+ /**
+ * Assign next available IP in prefix.
+ *
+ * @param prefix The prefix from which to get next available IP.
+ * @return The IPAddress
+ * @throws IpamException If something goes wrong.
+ */
+ IPAddress assign(Prefix prefix) throws IpamException;
+
+ /**
+ * Free the IP.
+ *
+ * @param ip The IP to release.
+ * @throws IpamException If something goes wrong.
+ */
+ void unassign(IPAddress ip) throws IpamException;
+}
+
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java
new file mode 100644
index 000000000..0520ad5e5
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImpl.java
@@ -0,0 +1,105 @@
+/*
+ * 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.impl;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonSerializer;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.util.concurrent.CompletionException;
+import org.apache.http.HttpResponse;
+import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
+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;
+
+public class NetboxClientImpl implements NetboxClient {
+
+ 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";
+
+ private final NetboxHttpClient client;
+ private final Gson gson;
+
+ public NetboxClientImpl(final NetboxHttpClient client) {
+ this.client = client;
+ final JsonSerializer<Status> vlanStatusDeserializer = (val, type, context) -> val.toJson();
+ gson = new GsonBuilder()
+ .registerTypeAdapter(Status.class, vlanStatusDeserializer)
+ .create();
+ }
+
+ @Override
+ public IPAddress assign(final Prefix prefix) throws IpamException {
+ checkArgument(prefix.getId() != null);
+ 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());
+ }
+ }
+
+ @Override
+ public void unassign(final IPAddress ipAddress) throws IpamException {
+ checkArgument(ipAddress.getId() != null);
+ 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());
+ }
+ }
+
+ @VisibleForTesting
+ IPAddress getIpAddress(final HttpResponse response) {
+ if (response.getStatusLine().getStatusCode() != 201) {
+ throw new IllegalStateException(NetboxHttpClient.getBodyAsString(response));
+ }
+ try (final Reader reader = new InputStreamReader(response.getEntity().getContent())) {
+ return gson.fromJson(reader, IPAddress.class);
+ } catch (final IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+
+ private static void checkArgument(final boolean argument) throws IpamException {
+ if (!argument) {
+ throw new IpamException(ID_MISSING_MSG);
+ }
+ }
+
+ private void checkResult(final HttpResponse response) {
+ if (response.getStatusLine().getStatusCode() - 200 >= 100) {
+ throw new IllegalStateException(
+ "Netbox request failed with status: " + NetboxHttpClient.getBodyAsString(response));
+ }
+ }
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java
new file mode 100644
index 000000000..a77b4d3e9
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClient.java
@@ -0,0 +1,151 @@
+/*
+ * 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.impl;
+
+import static org.apache.http.HttpHeaders.ACCEPT;
+import static org.apache.http.HttpHeaders.AUTHORIZATION;
+import static org.apache.http.HttpHeaders.CONTENT_TYPE;
+
+import java.io.IOException;
+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.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.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 String url;
+ private final String token;
+
+ // Used by the blueprint container
+ public NetboxHttpClient(NetboxProperties properties) {
+ this(properties.getHost(), properties.getApiKey());
+ }
+
+ NetboxHttpClient(final String url, final String token) {
+ this.url = url;
+ this.token = token;
+
+ final TrustStrategy acceptingTrustStrategy = (certificate, authType) -> true;
+ final SSLContext sslContext;
+ try {
+ sslContext = SSLContexts.custom()
+ .loadTrustMaterial(null, acceptingTrustStrategy).build();
+ } catch (final NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
+ throw new IllegalStateException("Can't create http client", e);
+ }
+ client = HttpAsyncClientBuilder.create()
+ .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
+ .setSSLContext(sslContext)
+ .build();
+
+ }
+
+ // Has to be public for blueprint container to access it
+ public void init() {
+ client.start();
+ }
+
+ @Override
+ public void close() throws IOException {
+ 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);
+ }
+
+ 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;
+ }
+
+ private <T extends HttpUriRequest> CompletionStage<HttpResponse> sendRequest(final String uri,
+ 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);
+ 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
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java
new file mode 100644
index 000000000..6d62fff9f
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/IPAddress.java
@@ -0,0 +1,58 @@
+/*
+ * 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 java.util.Objects;
+
+public class IPAddress extends Identifiable {
+
+ private Status.Values status;
+ private String address;
+
+ public void setStatus(Status.Values status) {
+ this.status = status;
+ }
+
+ public void setAddress(String address) {
+ this.address = address;
+ }
+
+ public Status.Values getStatus() {
+ return status;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ IPAddress ipAddress = (IPAddress) o;
+ return Objects.equals(status, ipAddress.status) &&
+ Objects.equals(address, ipAddress.address);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(status, address);
+ }
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java
new file mode 100644
index 000000000..501088d78
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Identifiable.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+public abstract class Identifiable {
+
+ private Integer id;
+
+ public Integer getId() {
+ return id;
+ }
+
+ public void setId(final Integer id) {
+ this.id = id;
+ }
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java
new file mode 100644
index 000000000..b20be91db
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Prefix.java
@@ -0,0 +1,20 @@
+/*
+ * 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;
+
+public class Prefix extends Identifiable {
+
+}
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
new file mode 100644
index 000000000..c56828a80
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/model/Status.java
@@ -0,0 +1,77 @@
+/*
+ * 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;
+ }
+
+ }
+}
diff --git a/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java
new file mode 100644
index 000000000..ee493ec18
--- /dev/null
+++ b/netbox-client/provider/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxProperties.java
@@ -0,0 +1,116 @@
+/*
+ * 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.property;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Set;
+
+import org.onap.ccsdk.sli.adaptors.netbox.api.IpamException;
+import org.onap.ccsdk.sli.core.utils.JREFileResolver;
+import org.onap.ccsdk.sli.core.utils.KarafRootFileResolver;
+import org.onap.ccsdk.sli.core.utils.PropertiesFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.BundleContextFileResolver;
+import org.onap.ccsdk.sli.core.utils.common.SdncConfigEnvVarFileResolver;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Responsible for determining the properties file to use.
+ *
+ * <ol>
+ * <li>A directory identified by the system environment variable <code>SDNC_CONFIG_DIR</code></li>
+ * <li>A directory identified by the JRE argument <code>netbox.properties</code></li>
+ * <li>A <code>netbox.properties</code> file located in the karaf root directory</li>
+ * </ol>
+ *
+ * Partial copy and adaptation of org.onap.ccsdk.sli.adaptors.aai.AAIServiceProvider
+ */
+public class NetboxProperties {
+
+ private static final Logger LOG = LoggerFactory.getLogger(NetboxProperties.class);
+
+ private static final String NETBOX_PROPERTY_FILE_NAME = "netbox.properties";
+ private static final String MISSING_PROPERTY_FILE =
+ "Missing configuration properties resource for Netbox: " + NETBOX_PROPERTY_FILE_NAME;
+ private static final String NETBOX_URL_PROP = "org.onap.ccsdk.sli.adaptors.netbox.url";
+ private static final String NETBOX_API_KEY_PROP = "org.onap.ccsdk.sli.adaptors.netbox.apikey";
+
+ private Set<PropertiesFileResolver> fileResolvers = new HashSet<>();
+ private Properties properties;
+
+ public NetboxProperties() {
+ fileResolvers.add(new SdncConfigEnvVarFileResolver("Using property file (1) from environment variable"));
+ fileResolvers.add(new BundleContextFileResolver("Using property file (2) from BundleContext property",
+ NetboxProperties.class));
+ fileResolvers.add(new JREFileResolver("Using property file (3) from JRE argument", NetboxProperties.class));
+ fileResolvers.add(new KarafRootFileResolver("Using property file (4) from karaf root", this));
+
+ loadProps();
+ }
+
+ public String getHost() {
+ checkArgument(properties != null);
+ return properties.getProperty(NETBOX_URL_PROP);
+ }
+
+ public String getApiKey() {
+ checkArgument(properties != null);
+ return properties.getProperty(NETBOX_API_KEY_PROP);
+ }
+
+ private void checkArgument(final boolean argument) {
+ if (!argument) {
+ LOG.info("Propety file {} was missing, trying to reload it", NETBOX_PROPERTY_FILE_NAME);
+ loadProps();
+ if (properties == null) {
+ throw new IllegalArgumentException(MISSING_PROPERTY_FILE);
+ }
+ }
+ }
+
+ private void loadProps() {
+ // determines properties file as according to the priority described in the class header comment
+ final File propertiesFile = determinePropertiesFile();
+ if (propertiesFile != null) {
+ try (FileInputStream fileInputStream = new FileInputStream(propertiesFile)) {
+ properties = new Properties();
+ properties.load(fileInputStream);
+ } catch (final IOException e) {
+ String errorMsg = "Failed to load properties for file: " + propertiesFile.toString();
+ LOG.error(errorMsg, new IpamException(errorMsg));
+ }
+ }
+ }
+
+ private File determinePropertiesFile() {
+ for (final PropertiesFileResolver resolver : fileResolvers) {
+ final Optional<File> fileOptional = resolver.resolveFile(NETBOX_PROPERTY_FILE_NAME);
+ if (fileOptional.isPresent()) {
+ final File file = fileOptional.get();
+ LOG.info("{} {}", resolver.getSuccessfulResolutionMessage(), file.getPath());
+ return file;
+ }
+ }
+
+ LOG.error(MISSING_PROPERTY_FILE, new IpamException(MISSING_PROPERTY_FILE));
+ return null;
+ }
+}
diff --git a/netbox-client/provider/src/main/resources/netbox.properties b/netbox-client/provider/src/main/resources/netbox.properties
new file mode 100755
index 000000000..ee5e67b43
--- /dev/null
+++ b/netbox-client/provider/src/main/resources/netbox.properties
@@ -0,0 +1,19 @@
+#
+# Copyright (C) 2018 AT&T, 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.
+#
+
+# Configuration file for Netbox client
+org.onap.ccsdk.sli.adaptors.netbox.url=http://localhost:9998
+org.onap.ccsdk.sli.adaptors.netbox.apikey=onceuponatimeiplayedwithnetbox20180814 \ No newline at end of file
diff --git a/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml b/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml
new file mode 100644
index 000000000..cf8a1af4d
--- /dev/null
+++ b/netbox-client/provider/src/main/resources/org/opendaylight/blueprint/netbox-client.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2018 AT&T, 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.
+ -->
+<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">
+
+ <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">
+ <argument ref="netboxProperty"/>
+ </bean>
+
+ <bean id="netboxClient" class="org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImpl">
+ <argument ref="httpClient"/>
+ </bean>
+
+ <service ref="netboxClient"
+ interface="org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient"
+ odl:type="default"/>
+
+</blueprint>