diff options
author | Matej Perina <matej.perina@pantheon.tech> | 2019-04-03 09:11:35 +0200 |
---|---|---|
committer | Timoney, Dan (dt5972) <dtimoney@att.com> | 2019-08-26 11:49:17 -0400 |
commit | b1dd81ede363508f83c86ed497b8c0815045f8e5 (patch) | |
tree | 878ee0532da4d02d3505fc6cbe93b77fd43fb45e /netbox-client/lighty | |
parent | 602de7cdf89676891604130d64e8bc4cc88c05f6 (diff) |
Proposal to remove OSGi dependencies from the CCSDK project
Dependencies on the OSGi frameworks and libraries are removed
by integrating the CCSDK project with the lighty.io.
It's a toolkit that allows to use ODL services (in this case
core services and the Restconf) without the dependency
on the Karaf framework and the Blueprint DI.
In this change are created the lighty.io modules which
initialize and expose same services as the Blueprint DI in
the blueprint.xml files.
More info about the lighty.io - https://lighty.io
Change-Id: Ia9eed2f60c71b7fc2e93b738c857d290b28e9420
Signed-off-by: Matej Perina <matej.perina@pantheon.tech>
Signed-off-by: Samuel Kontris <samuel.kontris@pantheon.tech>
Diffstat (limited to 'netbox-client/lighty')
5 files changed, 494 insertions, 0 deletions
diff --git a/netbox-client/lighty/pom.xml b/netbox-client/lighty/pom.xml new file mode 100755 index 000000000..18db29466 --- /dev/null +++ b/netbox-client/lighty/pom.xml @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8"?> +<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.4.0-SNAPSHOT</version> + <relativePath/> + </parent> + + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-lighty</artifactId> + <version>0.6.0-SNAPSHOT</version> + <packaging>jar</packaging> + + <name>ccsdk-sli-adaptors :: netbox-client :: ${project.artifactId}</name> + <url>http://maven.apache.org</url> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + </properties> + + <dependencyManagement> + <dependencies> + <dependency> + <groupId>org.onap.ccsdk.sli.core</groupId> + <artifactId>ccsdk-lighty-dependency-versions</artifactId> + <version>${project.version}</version> + <type>pom</type> + <scope>import</scope> + </dependency> + </dependencies> + </dependencyManagement> + + <dependencies> + <dependency> + <groupId>io.lighty.core</groupId> + <artifactId>lighty-controller</artifactId> + </dependency> + <dependency> + <groupId>org.onap.ccsdk.sli.adaptors</groupId> + <artifactId>netbox-client-provider</artifactId> + <version>${project.version}</version> + </dependency> + </dependencies> +</project> diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java new file mode 100644 index 000000000..2658c06cc --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxClientImplLighty.java @@ -0,0 +1,216 @@ +/* + * 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.collect.Lists; +import com.google.gson.JsonSyntaxException; +import java.io.IOException; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Map; +import javax.sql.rowset.CachedRowSet; +import org.apache.http.HttpResponse; +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.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; + +/** + * THIS CLASS IS A COPY OF {@link NetboxClientImpl} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxClientImplLighty implements NetboxClient { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxClientImplLighty.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/"; + + // 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, ip_address_type) \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 NetboxHttpClientLighty client; + private final DbLibService dbLibService; + + public NetboxClientImplLighty(final NetboxHttpClientLighty client, final DbLibService dbLibService) { + this.client = client; + this.dbLibService = dbLibService; + } + + @Override + public QueryStatus assignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + + try { + 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, + resourceName); + + 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 QueryStatus unassignIpAddress(final Map<String, String> parameters, final SvcLogicContext ctx) { + try { + SliPluginUtils + .checkParameters(parameters, new String[]{SERVICE_INSTANCE_ID_PROP, EXTERNAL_KEY_PROP}, + LOG); + } catch (SvcLogicException e) { + return QueryStatus.FAILURE; + } + + 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; + } + + 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; + } + + if (httpResp.getStatusLine().getStatusCode() - 200 >= 100) { + LOG.error("Fail to unassign IP for IPAddress(id={}). HTTP code={}.", ipAddressId, + httpResp.getStatusLine().getStatusCode()); + return QueryStatus.FAILURE; + } + + 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; + } +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java new file mode 100644 index 000000000..388486c4f --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/impl/NetboxHttpClientLighty.java @@ -0,0 +1,97 @@ +/* + * 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 javax.net.ssl.SSLContext; +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.HttpRequestBase; +import org.apache.http.conn.ssl.NoopHostnameVerifier; +import org.apache.http.entity.StringEntity; +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.property.NetboxPropertiesLighty; + +/** + * THIS CLASS IS A COPY OF {@link NetboxHttpClient} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxHttpClientLighty implements AutoCloseable { + + private static final String APPLICATION_JSON = "application/json"; + + private final CloseableHttpClient client; + private final String url; + private final String token; + + // Used by the blueprint container + public NetboxHttpClientLighty(NetboxPropertiesLighty properties) { + this(properties.getHost(), properties.getApiKey()); + } + + NetboxHttpClientLighty(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 = HttpClientBuilder.create() + .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) + .setSSLContext(sslContext) + .build(); + } + + @Override + public void close() throws IOException { + client.close(); + } + + 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); + } + + HttpResponse delete(final String uri) throws IOException { + final HttpDelete request = new HttpDelete(url + uri); + setHeaders(request); + return client.execute(request); + } + + private void setHeaders(final HttpRequestBase request) { + request.addHeader(ACCEPT, APPLICATION_JSON); + request.addHeader(CONTENT_TYPE, APPLICATION_JSON); + request.addHeader(AUTHORIZATION, "Token " + token); + } +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java new file mode 100644 index 000000000..13f7963bb --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/lighty/NetboxClientModule.java @@ -0,0 +1,70 @@ +/* + * ============LICENSE_START========================================== + * Copyright (c) 2019 PANTHEON.tech s.r.o. + * =================================================================== + * 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.ccsdk.sli.adaptors.netbox.lighty; + +import io.lighty.core.controller.api.AbstractLightyModule; +import java.io.IOException; +import org.onap.ccsdk.sli.adaptors.netbox.api.NetboxClient; +import org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxClientImplLighty; +import org.onap.ccsdk.sli.adaptors.netbox.impl.NetboxHttpClientLighty; +import org.onap.ccsdk.sli.adaptors.netbox.property.NetboxPropertiesLighty; +import org.onap.ccsdk.sli.core.dblib.DbLibService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * The implementation of the {@link io.lighty.core.controller.api.LightyModule} that manages and provides services from + * the netbox-client-provider artifact. + */ +public class NetboxClientModule extends AbstractLightyModule { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxClientModule.class); + + private final DbLibService dbLibService; + + private NetboxPropertiesLighty netboxProperties; + private NetboxHttpClientLighty netboxHttpClient; + private NetboxClientImplLighty netboxClient; + + public NetboxClientModule(DbLibService dbLibService) { + this.dbLibService = dbLibService; + } + + @Override + protected boolean initProcedure() { + this.netboxProperties = new NetboxPropertiesLighty(); + this.netboxHttpClient = new NetboxHttpClientLighty(netboxProperties); + this.netboxClient = new NetboxClientImplLighty(netboxHttpClient, dbLibService); + return true; + } + + @Override + protected boolean stopProcedure() { + try { + netboxHttpClient.close(); + } catch (IOException e) { + LOG.error("Exception thrown while closing {}!", netboxHttpClient.getClass(), e); + return false; + } + return true; + } + + public NetboxClient getNetboxClient() { + return netboxClient; + } + +} diff --git a/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java new file mode 100644 index 000000000..15759c721 --- /dev/null +++ b/netbox-client/lighty/src/main/java/org/onap/ccsdk/sli/adaptors/netbox/property/NetboxPropertiesLighty.java @@ -0,0 +1,64 @@ +/* + * 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.FileInputStream; +import java.util.Properties; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * THIS CLASS IS A COPY OF {@link NetboxProperties} WITH REMOVED OSGi DEPENDENCIES + */ +public class NetboxPropertiesLighty { + + private static final Logger LOG = LoggerFactory.getLogger(NetboxPropertiesLighty.class); + + private static final String NETBOX_PROPERTY_FILE_NAME = "netbox.properties"; + private static final String DEFAULT_PROPERTIES_DIR = "/opt/onap/ccsdk/data/properties"; + private static final String PROPERTIES_DIR_KEY = "SDNC_CONFIG_DIR"; + + 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 Properties properties; + + public NetboxPropertiesLighty() { + loadProps(); + } + + public String getHost() { + return properties.getProperty(NETBOX_URL_PROP); + } + + public String getApiKey() { + return properties.getProperty(NETBOX_API_KEY_PROP); + } + + private void loadProps() { + properties = new Properties(); + // Try to load config from dir + final String ccsdkConfigDir = + System.getProperty(PROPERTIES_DIR_KEY, DEFAULT_PROPERTIES_DIR) + "/" + NETBOX_PROPERTY_FILE_NAME; + LOG.info("Loading properties from file {}", ccsdkConfigDir); + try (FileInputStream in = new FileInputStream(ccsdkConfigDir)) { + properties.load(in); + LOG.info("Loaded {} properties from file {}", properties.size(), ccsdkConfigDir); + } catch (Exception e) { + LOG.error("Failed to load properties for file: {} " + NETBOX_PROPERTY_FILE_NAME, e); + } + } +} |