diff options
author | Denes Nemeth <denes.nemeth@nokia.com> | 2018-02-12 20:55:54 +0100 |
---|---|---|
committer | Denes Nemeth <denes.nemeth@nokia.com> | 2018-02-23 11:44:45 +0100 |
commit | b17042b955489d8a023d09abad5436ff9b900dc3 (patch) | |
tree | 1e4392ac04a2fb1ed8d17075d504cf6594acaf16 /nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap | |
parent | d4982f7b1777e9cdae9a4cc7d0d104263889ac69 (diff) |
Updating Nokia driver
Change-Id: I950afe6acbdb359cd67a448024f006a45e8fc293
Signed-off-by: Denes Nemeth <denes.nemeth@nokia.com>
Issue-ID: VFC-728
Diffstat (limited to 'nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap')
11 files changed, 1138 insertions, 0 deletions
diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/GenericExternalSystemInfoProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/GenericExternalSystemInfoProvider.java new file mode 100644 index 00000000..3e1e05a5 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/GenericExternalSystemInfoProvider.java @@ -0,0 +1,83 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core; + +import com.google.common.cache.CacheLoader; +import com.google.common.cache.LoadingCache; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.VimInfoProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.VnfmInfoProvider; +import org.onap.vnfmdriver.model.VnfmInfo; +import org.slf4j.Logger; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.core.env.Environment; + +import java.util.concurrent.TimeUnit; + +import static com.google.common.cache.CacheBuilder.newBuilder; +import static java.lang.Long.valueOf; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.fatalFailure; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for providing access to core systems + */ +abstract public class GenericExternalSystemInfoProvider extends IpMappingProvider implements VnfmInfoProvider, VimInfoProvider, InitializingBean { + private static Logger logger = getLogger(GenericExternalSystemInfoProvider.class); + private final Environment environment; + private LoadingCache<String, VnfmInfo> vnfmInfoCache; + + public GenericExternalSystemInfoProvider(Environment environment) { + super(environment); + this.environment = environment; + } + + /** + * After the Bean has been initialized the IP mapping and the VMFM cache is initialized + * It is done in this phase because the logic requires the the @Value anoted fields to + * be specified + */ + @Override + public void afterPropertiesSet() throws Exception { + super.afterPropertiesSet(); + vnfmInfoCache = newBuilder().expireAfterWrite(environment.getProperty(VNFM_INFO_CACHE_EVICTION_IN_MS, Long.class, valueOf(DEFAULT_CACHE_EVICTION_TIMEOUT_IN_MS)), TimeUnit.MILLISECONDS).concurrencyLevel(1).build(new CacheLoader<String, VnfmInfo>() { + @Override + public VnfmInfo load(String vnfmId) throws Exception { + logger.info("Quering VNFM info from source with " + vnfmId + " identifier"); + return queryVnfmInfoFromSource(vnfmId); + } + }); + } + + /* + * @param vnfmId the identifier of the VNFM + * @return the cached VNFM + */ + public VnfmInfo getVnfmInfo(String vnfmId) { + try { + return vnfmInfoCache.get(vnfmId); + } catch (Exception e) { + throw fatalFailure(logger, "Unable to query VNFM info for " + vnfmId, e); + } + } + + /** + * Load the information related to the VNFM from the remote source + * + * @param vnfmId the identifier of the VNFM + * @return the description of the VNFM + */ + public abstract VnfmInfo queryVnfmInfoFromSource(String vnfmId); +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/IpMappingProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/IpMappingProvider.java new file mode 100644 index 00000000..a2472283 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/IpMappingProvider.java @@ -0,0 +1,69 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core; + +import org.springframework.beans.factory.InitializingBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Consumer; + +import static com.google.common.base.Splitter.on; +import static com.google.common.collect.Lists.newArrayList; + +/** + * Responsible for remapping IP/DNS names in URLs based on property file + */ +@Component +public class IpMappingProvider implements InitializingBean { + public static final String IP_MAP = "ipMap"; + private final Environment environment; + private final Map<String, String> ipMap = new HashMap<>(); + + @Autowired + IpMappingProvider(Environment environment) { + this.environment = environment; + } + + /** + * After the Bean has been initialized the IP mapping and the VMFM cache is initialized + * It is done in this phase because it requires the environment to be initialized + */ + @Override + public void afterPropertiesSet() throws Exception { + on(",").trimResults().omitEmptyStrings().split(environment.getProperty(IP_MAP, String.class, "")).forEach(new Consumer<String>() { + @Override + public void accept(String item) { + ArrayList<String> ip = newArrayList(on("->").trimResults().split(item)); + ipMap.put(ip.get(0), ip.get(1)); + } + }); + } + + /** + * Map IP addresses based on configuration parameter ipMap + * + * @param ip the original IP address + * @return the mapped IP address + */ + public String mapPrivateIpToPublicIp(String ip) { + return ipMap.getOrDefault(ip, ip); + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java new file mode 100644 index 00000000..b6f4644a --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/MsbApiProvider.java @@ -0,0 +1,85 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core; + +import org.onap.msb.sdk.discovery.common.RouteException; +import org.onap.msb.sdk.discovery.entity.MicroServiceFullInfo; +import org.onap.msb.sdk.discovery.entity.NodeInfo; +import org.onap.msb.sdk.httpclient.msb.MSBServiceClient; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import static java.lang.Integer.valueOf; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.fatalFailure; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for providing REST client to access MSB API + */ +@Component +public class MsbApiProvider extends IpMappingProvider { + private static Logger logger = getLogger(MsbApiProvider.class); + @Value("${messageBusIp}") + private String messageBusIp; + @Value("${messageBusPort}") + private String messageBusPort; + + @Autowired + MsbApiProvider(Environment environment) { + super(environment); + } + + /** + * @return API to access ONAP MSB + */ + public MSBServiceClient getMsbClient() { + return new MSBServiceClient(messageBusIp, valueOf(messageBusPort)); + } + + /** + * @param name the name of the micro service + * @param version the version of the micro service + * @return the base URL of the micro service (ex. https://1.2.3.4/path ) + */ + public String getMicroServiceUrl(String name, String version) { + MicroServiceFullInfo microServiceFullInfo = getMicroServiceInfo(name, version); + String protocol = "http://"; //FIXME the enable_ssl field should be used, but it is not available in SDK + String ipAnPort = getNodeIpAnPort(microServiceFullInfo); + //the field name in A&AI is misleading the URL is relative path postfixed to http(s)://ip:port + String fullUrl = protocol + ipAnPort + microServiceFullInfo.getUrl(); + return fullUrl; + } + + private MicroServiceFullInfo getMicroServiceInfo(String name, String version) throws RuntimeException { + try { + return getMsbClient().queryMicroServiceInfo(name, version); + } catch (RouteException e) { + throw fatalFailure(logger, "Unable to get micro service URL for " + name + " with version " + version, e); + } + } + + private String getNodeIpAnPort(MicroServiceFullInfo microServiceFullInfo) { + for (NodeInfo nodeInfo : microServiceFullInfo.getNodes()) { + if (!nodeInfo.getIp().startsWith("172.")) { // FIXME how to know which of the multiple addresses to use? + return mapPrivateIpToPublicIp(nodeInfo.getIp()) + ":" + nodeInfo.getPort(); + } + } + throw fatalFailure(logger, "The " + microServiceFullInfo.getServiceName() + " service with " + microServiceFullInfo.getVersion() + " does not have any valid nodes" + microServiceFullInfo.getNodes()); + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java new file mode 100644 index 00000000..3b2f1d34 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/SelfRegistrationManager.java @@ -0,0 +1,194 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core; + +import com.nokia.cbam.lcn.v32.ApiException; +import com.nokia.cbam.lcn.v32.api.SubscriptionsApi; +import com.nokia.cbam.lcn.v32.model.*; +import org.onap.msb.sdk.discovery.common.RouteException; +import org.onap.msb.sdk.discovery.entity.MicroServiceFullInfo; +import org.onap.msb.sdk.discovery.entity.MicroServiceInfo; +import org.onap.msb.sdk.discovery.entity.Node; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.HashSet; + +import static com.nokia.cbam.lcn.v32.model.SubscriptionAuthentication.TypeEnum.NONE; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCN_API_VERSION; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for registering the driver in the core systems. + */ +@Component +public class SelfRegistrationManager { + public static final String DRIVER_VERSION = "v1"; + public static final String SERVICE_NAME = "NokiaSVNFM"; + // 1 means internal 0 means core :) + public static final String INTERNAL_SERVICE = "1"; + public static final String SWAGGER_API_DEFINITION = "self.swagger.json"; + private static Logger logger = getLogger(SelfRegistrationManager.class); + private final DriverProperties driverProperties; + private final MsbApiProvider msbApiProvider; + private final CbamRestApiProvider cbamRestApiProvider; + + @Value("${driverMsbExternalIp}") + private String driverMsbExternalIp; + @Value("${driverVnfmExternalIp}") + private String driverVnfmExternalIp; + @Value("${server.port}") + private String driverPort; + private volatile boolean ready = false; + + @Autowired + SelfRegistrationManager(DriverProperties driverProperties, MsbApiProvider msbApiProvider, CbamRestApiProvider cbamRestApiProvider) { + this.cbamRestApiProvider = cbamRestApiProvider; + this.msbApiProvider = msbApiProvider; + this.driverProperties = driverProperties; + } + + /** + * Register the driver in micro-service bus and subscribe to LCNs from CBAM + */ + public void register() { + //the order is important (only publish it's existence after the subscription has been created) + subscribeToLcn(driverProperties.getVnfmId()); + try { + registerMicroService(); + } catch (RuntimeException e) { + deleteSubscription(driverProperties.getVnfmId()); + throw e; + } + ready = true; + } + + /** + * De-register the VNFM driver from the micro-service bus + */ + public void deRegister() { + try { + logger.info("Cancelling micro service registration"); + msbApiProvider.getMsbClient().cancelMicroServiceInfo(SERVICE_NAME, DRIVER_VERSION); + } catch (RouteException e) { + //ONAP throws 500 internal server error, but deletes the micro service + try { + MicroServiceFullInfo microServiceFullInfo = msbApiProvider.getMsbClient().queryMicroServiceInfo(SERVICE_NAME, DRIVER_VERSION); + logger.error("Unable to deRegister Nokia VNFM driver", e); + //the micro service still exists + throw new RuntimeException(e); + } catch (RouteException e1) { + // the micro service was deleted (even though 500 HTTP code was reported) + } + } + deleteSubscription(driverProperties.getVnfmId()); + } + + /** + * @return the swagger API definition + */ + public byte[] getSwaggerApiDefinition() { + return SystemFunctions.systemFunctions().loadFile(SWAGGER_API_DEFINITION); + } + + private String getDriverVnfmUrl() { + return "http://" + driverVnfmExternalIp + ":" + driverPort + DriverProperties.BASE_URL; + } + + private void deleteSubscription(String vnfmId) { + logger.info("Deleting CBAM LCN subscription"); + SubscriptionsApi lcnApi = cbamRestApiProvider.getCbamLcnApi(vnfmId); + try { + String callbackUrl = getDriverVnfmUrl() + DriverProperties.LCN_PATH; + for (Subscription subscription : lcnApi.subscriptionsGet(NOKIA_LCN_API_VERSION)) { + if (subscription.getCallbackUrl().equals(callbackUrl)) { + lcnApi.subscriptionsSubscriptionIdDelete(subscription.getId(), NOKIA_LCN_API_VERSION); + } + } + } catch (ApiException e) { + logger.error("Unable to delete CBAM LCN subscription"); + throw new RuntimeException(e); + } + } + + private MicroServiceFullInfo registerMicroService() { + logger.info("Registering micro service"); + MicroServiceInfo microServiceInfo = new MicroServiceInfo(); + microServiceInfo.setUrl(DriverProperties.BASE_URL); + //the PATH should not be set + microServiceInfo.setProtocol("REST"); + microServiceInfo.setVisualRange(INTERNAL_SERVICE); + microServiceInfo.setServiceName(SERVICE_NAME); + microServiceInfo.setVersion(DRIVER_VERSION); + //FIXME set enable_ssl to false after the field has been added to MSB SDK + //currently defaults to false, which is good + Node node = new Node(); + microServiceInfo.setNodes(new HashSet<>()); + microServiceInfo.getNodes().add(node); + node.setIp(driverMsbExternalIp); + node.setPort(driverPort); + node.setTtl("0"); + try { + return msbApiProvider.getMsbClient().registerMicroServiceInfo(microServiceInfo); + } catch (RouteException e) { + logger.error("Unable to register Nokia VNFM driver", e); + throw new RuntimeException(e); + } + } + + private void subscribeToLcn(String vnfmId) { + String callbackUrl = getDriverVnfmUrl() + DriverProperties.LCN_PATH; + logger.info("Subscribing to CBAM LCN " + driverProperties.getCbamLcnUrl() + " with callback to " + callbackUrl); + SubscriptionsApi lcnApi = cbamRestApiProvider.getCbamLcnApi(vnfmId); + try { + for (Subscription subscription : lcnApi.subscriptionsGet(NOKIA_LCN_API_VERSION)) { + if (subscription.getCallbackUrl().equals(callbackUrl)) { + return; + } + } + CreateSubscriptionRequest request = new CreateSubscriptionRequest(); + request.setFilter(new SubscriptionFilter()); + request.getFilter().setNotificationTypes(new ArrayList<>()); + request.getFilter().getNotificationTypes().add(VnfNotificationType.VNFLIFECYCLECHANGENOTIFICATION); + request.setCallbackUrl(callbackUrl); + request.getFilter().addOperationTypesItem(OperationType.HEAL); + request.getFilter().addOperationTypesItem(OperationType.INSTANTIATE); + request.getFilter().addOperationTypesItem(OperationType.SCALE); + request.getFilter().addOperationTypesItem(OperationType.TERMINATE); + SubscriptionAuthentication subscriptionAuthentication = new SubscriptionAuthentication(); + subscriptionAuthentication.setType(NONE);//FIXME improve authentication + request.setAuthentication(subscriptionAuthentication); + lcnApi.subscriptionsPost(request, NOKIA_LCN_API_VERSION); + } catch (ApiException e) { + logger.error("Unable to subscribe to CBAM LCN", e); + throw new RuntimeException(e); + } + } + + /** + * @return is the component ready to serve requests + */ + public boolean isReady() { + return ready; + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/package-info.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/package-info.java new file mode 100644 index 00000000..67bdef8a --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/core/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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. + */ + +/** + * Handles communication with ONAP core functions + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core; diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/package-info.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/package-info.java new file mode 100644 index 00000000..eea0066b --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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. + */ + +/** + * Handles information exchange with ONAP components + */ +package org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap; diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcExternalSystemInfoProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcExternalSystemInfoProvider.java new file mode 100644 index 00000000..1959e480 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcExternalSystemInfoProvider.java @@ -0,0 +1,64 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc; + +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.GenericExternalSystemInfoProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vnfmdriver.ApiException; +import org.onap.vnfmdriver.model.VimInfo; +import org.onap.vnfmdriver.model.VnfmInfo; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Component; + +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.fatalFailure; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for providing information related to the VNFM from VF-C source + */ +@Component +@Conditional(value = Conditions.UseForVfc.class) +public class VfcExternalSystemInfoProvider extends GenericExternalSystemInfoProvider { + private static Logger logger = getLogger(VfcExternalSystemInfoProvider.class); + private final VfcRestApiProvider vfcRestApiProvider; + + @Autowired + VfcExternalSystemInfoProvider(Environment environment, VfcRestApiProvider vfcRestApiProvider) { + super(environment); + this.vfcRestApiProvider = vfcRestApiProvider; + } + + @Override + public VnfmInfo queryVnfmInfoFromSource(String vnfmId) { + try { + return vfcRestApiProvider.getNsLcmApi().queryVnfmInfo(vnfmId); + } catch (ApiException e) { + throw fatalFailure(logger, "Unable to query VNFM from VF-C with " + vnfmId + " identifier", e); + } + } + + @Override + public VimInfo getVimInfo(String vimId) { + try { + return vfcRestApiProvider.getNsLcmApi().queryVIMInfo(vimId); + } catch (org.onap.vnfmdriver.ApiException e) { + throw fatalFailure(logger, "Unable to query VIM from VF-C with " + vimId + " identifier", e); + } + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java new file mode 100644 index 00000000..fd68aebe --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcGrantManager.java @@ -0,0 +1,220 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.nokia.cbam.lcm.v32.ApiException; +import com.nokia.cbam.lcm.v32.model.VnfInfo; +import com.nokia.cbam.lcm.v32.model.VnfcResourceInfo; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IGrantManager; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CatalogManager; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider; +import org.onap.vnfmdriver.model.*; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; +import org.yaml.snakeyaml.Yaml; + +import java.util.*; + +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.CbamRestApiProvider.NOKIA_LCM_API_VERSION; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for handling granting before the execution of a VNF operation + */ +@Component +@Conditional(value = Conditions.UseForVfc.class) +public class VfcGrantManager implements IGrantManager { + private static Logger logger = getLogger(VfcGrantManager.class); + private final CatalogManager catalogManager; + private final CbamRestApiProvider cbamRestApiProvider; + private final VfcRestApiProvider vfcRestApiProvider; + + @Autowired + VfcGrantManager(CatalogManager catalogManager, CbamRestApiProvider cbamRestApiProvider, VfcRestApiProvider vfcRestApiProvider) { + this.catalogManager = catalogManager; + this.cbamRestApiProvider = cbamRestApiProvider; + this.vfcRestApiProvider = vfcRestApiProvider; + } + + @Override + public void requestGrantForHeal(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfHealRequest request, String jobId) { + GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, OperationType.HEAL); + ResourceChange resourceChange = new ResourceChange(); + resourceChange.setType(ChangeType.VDU); + resourceChange.setVdu(request.getAffectedvm().getVduid()); + resourceChange.setResourceDefinitionId(UUID.randomUUID().toString()); + grantRequest.getRemoveResource().add(resourceChange); + grantRequest.getAddResource().add(resourceChange); + grantRequest.setVnfInstanceId(vnfId); + requestGrant(grantRequest); + } + + @Override + public void requestGrantForScale(String vnfmId, String vnfId, String vimId, String onapCsarId, VnfScaleRequest request, String jobId) { + try { + OperationType operationType = ScaleDirection.IN.equals(request.getType()) ? OperationType.SCALEIN : OperationType.SCALEOUT; + GrantVNFRequest grantRequest = buildGrantRequest(vnfmId, vimId, onapCsarId, jobId, operationType); + com.nokia.cbam.lcm.v32.model.VnfInfo vnf = cbamRestApiProvider.getCbamLcmApi(vnfmId).vnfsVnfInstanceIdGet(vnfId, NOKIA_LCM_API_VERSION); + String vnfdContent = catalogManager.getCbamVnfdContent(vnfmId, vnf.getVnfdId()); + Set<ResourceChange> resourceChanges = calculateResourceChangeDuringScaling(vnfdContent, request.getAspectId(), Integer.parseInt(request.getNumberOfSteps())); + switch (request.getType()) { + case IN: + grantRequest.getRemoveResource().addAll(resourceChanges); + break; + case OUT: + grantRequest.getAddResource().addAll(resourceChanges); + break; + } + grantRequest.setVnfInstanceId(vnfId); + requestGrant(grantRequest); + } catch (ApiException e) { + logger.error("Unable to query VNF " + vnfId, e); + throw new RuntimeException("Unable to query VNF " + vnfId, e); + } + } + + @Override + public void requestGrantForTerminate(String vnfmId, String vnfId, String vimId, String onapVnfdId, VnfInfo vnf, String jobId) { + switch (vnf.getInstantiationState()) { + case NOT_INSTANTIATED: + break; + case INSTANTIATED: + GrantVNFRequest grantRequest; + try { + grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, OperationType.TERMINAL); + if (vnf.getInstantiatedVnfInfo().getVnfcResourceInfo() != null) { + for (VnfcResourceInfo vnfc : vnf.getInstantiatedVnfInfo().getVnfcResourceInfo()) { + ResourceChange resourceChange = new ResourceChange(); + grantRequest.getRemoveResource().add(resourceChange); + resourceChange.setVdu(vnfc.getVduId()); + resourceChange.setType(ChangeType.VDU); + resourceChange.setResourceDefinitionId(UUID.randomUUID().toString()); + } + } + grantRequest.setVnfInstanceId(vnfId); + } catch (Exception e) { + logger.error("Unable to prepare grant request for termination", e); + throw new RuntimeException("Unable to prepare grant request for termination", e); + } + requestGrant(grantRequest); + break; + } + } + + @Override + public GrantVNFResponseVim requestGrantForInstantiate(String vnfmId, String vnfId, String vimId, String onapVnfdId, String instantiationLevelId, String cbamVnfdContent, String jobId) { + GrantVNFRequest grantRequest; + try { + grantRequest = buildGrantRequest(vnfmId, vimId, onapVnfdId, jobId, OperationType.INSTANTIATE); + grantRequest.setVnfInstanceId(vnfId); + grantRequest.setAddResource(new ArrayList<>()); + grantRequest.getAddResource().addAll(calculateResourceChangeDuringInstantiate(cbamVnfdContent, instantiationLevelId)); + } catch (Exception e) { + logger.error("Unable to prepare grant request for instantiation", e); + throw new RuntimeException("Unable to prepare grant request for instantiation", e); + } + return requestGrant(grantRequest); + } + + private GrantVNFRequest buildGrantRequest(String vnfmId, String vimId, String onapCsarId, String jobId, OperationType operationType) { + //FIXME the vimId should not be required for grant request see VFC-603 issue + GrantVNFRequest grantVNFRequest = new GrantVNFRequest(); + grantVNFRequest.setAdditionalParam(new AdditionalGrantParams(vnfmId, vimId)); + grantVNFRequest.setVnfDescriptorId(onapCsarId); + grantVNFRequest.setJobId(jobId); + grantVNFRequest.setLifecycleOperation(operationType); + grantVNFRequest.setAddResource(new ArrayList<>()); + grantVNFRequest.setRemoveResource(new ArrayList<>()); + return grantVNFRequest; + } + + private GrantVNFResponseVim requestGrant(GrantVNFRequest grantRequest) { + try { + return vfcRestApiProvider.getNsLcmApi().grantvnf(grantRequest).getVim(); + } catch (org.onap.vnfmdriver.ApiException e) { + logger.error("Unable to request grant", e); + throw new RuntimeException(e); + } + } + + private Set<ResourceChange> calculateResourceChangeDuringInstantiate(String vnfdContent, String instantiationLevelId) { + JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject(); + JsonObject capabilities = CbamUtils.child(CbamUtils.child(CbamUtils.child(root, "topology_template"), "substitution_mappings"), "capabilities"); + JsonObject deploymentFlavorProperties = CbamUtils.child(CbamUtils.child(capabilities, "deployment_flavour"), "properties"); + JsonObject instantiationLevels = CbamUtils.child(deploymentFlavorProperties, "instantiation_levels"); + Set<ResourceChange> resourceChanges = new HashSet<>(); + for (Map.Entry<String, JsonElement> vdu_level : CbamUtils.child(CbamUtils.child(instantiationLevels, instantiationLevelId), ("vdu_levels")).entrySet()) { + JsonElement number_of_instances = vdu_level.getValue().getAsJsonObject().get("number_of_instances"); + for (int i = 0; i < number_of_instances.getAsLong(); i++) { + ResourceChange resourceChange = new ResourceChange(); + resourceChanges.add(resourceChange); + resourceChange.setVdu(vdu_level.getKey()); + resourceChange.setType(ChangeType.VDU); + resourceChange.setResourceDefinitionId(UUID.randomUUID().toString()); + } + } + return resourceChanges; + } + + private Set<ResourceChange> calculateResourceChangeDuringScaling(String vnfdContent, String aspectId, int steps) { + JsonObject root = new Gson().toJsonTree(new Yaml().load(vnfdContent)).getAsJsonObject(); + Set<ResourceChange> resourceChanges = new HashSet<>(); + JsonArray policies = CbamUtils.child(root, "topology_template").getAsJsonObject().get("policies").getAsJsonArray(); + for (JsonElement policy : policies) { + if (policy.getAsJsonObject().entrySet().iterator().next().getKey().equals("heat_mapping")) { + JsonObject aspects = policy.getAsJsonObject().entrySet().iterator().next().getValue().getAsJsonObject().get("properties").getAsJsonObject().get("aspects").getAsJsonObject(); + JsonObject aspect = aspects.get(aspectId).getAsJsonObject(); + if (aspect.has("vdus")) { + for (Map.Entry<String, JsonElement> vdu : aspect.get("vdus").getAsJsonObject().entrySet()) { + String vduId = vdu.getKey(); + for (int step = 0; step < steps; step++) { + for (int i = 0; i < vdu.getValue().getAsJsonArray().size(); i++) { + ResourceChange resourceChange = new ResourceChange(); + resourceChange.setVdu(vduId); + resourceChange.setType(ChangeType.VDU); + resourceChange.setResourceDefinitionId(UUID.randomUUID().toString()); + resourceChanges.add(resourceChange); + } + } + } + } + } + } + return resourceChanges; + } + + /** + * Represents the mandatory parameters that must be sent during grant request to VF-C + */ + private static class AdditionalGrantParams { + private final String vnfmId; + private final String vimId; + + AdditionalGrantParams(String vnfmId, String vimId) { + this.vnfmId = vnfmId; + this.vimId = vimId; + } + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java new file mode 100644 index 00000000..26439b5c --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcNotificationSender.java @@ -0,0 +1,202 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc; + +import com.google.gson.Gson; +import com.nokia.cbam.lcm.v32.model.OperationExecution; +import com.nokia.cbam.lcm.v32.model.ScaleVnfRequest; +import com.nokia.cbam.lcm.v32.model.VnfLifecycleChangeNotification; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.INotificationSender; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.DriverProperties; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedConnectionPoints; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.notification.ReportedAffectedCp; +import org.onap.vnfmdriver.model.*; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; + +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.fatalFailure; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.ILifecycleChangeNotificationManager.SEPARATOR; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.vnfm.JobManager.extractOnapJobId; +import static org.slf4j.LoggerFactory.getLogger; + +/** + * Responsible for sending notifications to VF-C + */ +@Component +@Conditional(value = Conditions.UseForVfc.class) +public class VfcNotificationSender implements INotificationSender { + private static Logger logger = getLogger(VfcNotificationSender.class); + private final DriverProperties driverProperties; + private final VfcRestApiProvider vfcRestApiProvider; + + @Autowired + VfcNotificationSender(DriverProperties driverProperties, VfcRestApiProvider vfcRestApiProvider) { + this.driverProperties = driverProperties; + this.vfcRestApiProvider = vfcRestApiProvider; + } + + @Override + public void processNotification(VnfLifecycleChangeNotification recievedNotification, OperationExecution operationExecution, ReportedAffectedConnectionPoints affectedCps, String vimId) { + VNFLCMNotification notificationToSend = new VNFLCMNotification(); + notificationToSend.setJobId(extractOnapJobId(operationExecution.getOperationParams())); + notificationToSend.setOperation(getOperation(driverProperties.getVnfmId(), recievedNotification.getVnfInstanceId(), operationExecution, recievedNotification.getOperation(), recievedNotification.getAffectedVnfcs())); + notificationToSend.setVnfInstanceId(recievedNotification.getVnfInstanceId()); + switch (recievedNotification.getStatus()) { + case FINISHED: + case FAILED: + notificationToSend.setStatus(VnfLcmNotificationStatus.RESULT); + addAffectedVirtualLinks(recievedNotification, notificationToSend); + addAffectedVnfcs(vimId, recievedNotification.getVnfInstanceId(), notificationToSend, recievedNotification); + addAffectedCps(vimId, notificationToSend, affectedCps); + break; + default: + notificationToSend.setStatus(VnfLcmNotificationStatus.START); + break; + } + sendNotification(notificationToSend); + } + + private void sendNotification(VNFLCMNotification notification) { + try { + logger.info("Sending LCN: " + new Gson().toJson(notification)); + vfcRestApiProvider.getNsLcmApi().vNFLCMNotification(driverProperties.getVnfmId(), notification.getVnfInstanceId(), notification); + } catch (Exception e) { + fatalFailure(logger, "Unable to send LCN to VF-C", e); + } + } + + private AffectedCp buildAffectedCp(String vimId, String vnfId, ReportedAffectedCp affectedCp) { + AffectedCp onapAffectedCp = new AffectedCp(); + AffectedCpPortResource port = new AffectedCpPortResource(); + port.setInstId(affectedCp.getServerProviderId()); + port.setIpAddress(affectedCp.getIpAddress()); + port.setMacAddress(affectedCp.getMacAddress()); + port.setResourceid(affectedCp.getProviderId()); + port.setResourceName(affectedCp.getName()); + port.setTenant(affectedCp.getTenantId()); + port.setVimid(vimId); + onapAffectedCp.setPortResource(port); + onapAffectedCp.setCpdid(affectedCp.getCpId()); + onapAffectedCp.setCpinstanceid(vnfId + SEPARATOR + affectedCp.getCpId()); + onapAffectedCp.setVirtualLinkInstanceId(affectedCp.getNetworkProviderId()); + onapAffectedCp.setChangeType(transform(affectedCp.getChangeType())); + //owner id & type can be left empty it will default to VNF id on VF-C + return onapAffectedCp; + } + + private VnfCpNotificationType transform(com.nokia.cbam.lcm.v32.model.ChangeType changeType) { + switch (changeType) { + case ADDED: + return VnfCpNotificationType.ADDED; + case REMOVED: + return VnfCpNotificationType.REMOVED; + default: //can only be MODIFIED + return VnfCpNotificationType.CHANGED; + } + } + + private void addAffectedVnfcs(String vimId, String vnfId, VNFLCMNotification notificationToSend, VnfLifecycleChangeNotification request) { + if (request.getAffectedVnfcs() != null) { + notificationToSend.setAffectedVnfc(new ArrayList<>()); + for (com.nokia.cbam.lcm.v32.model.AffectedVnfc affectedVnfc : request.getAffectedVnfcs()) { + org.onap.vnfmdriver.model.AffectedVnfc onapVnfc = new org.onap.vnfmdriver.model.AffectedVnfc(); + onapVnfc.setChangeType(getChangeType(affectedVnfc.getChangeType())); + onapVnfc.setVduId(affectedVnfc.getVduId()); + onapVnfc.setVmid(affectedVnfc.getComputeResource().getResourceId()); + onapVnfc.setVmname(extractServerName(affectedVnfc.getComputeResource().getAdditionalData())); + onapVnfc.setVnfcInstanceId(vnfId + SEPARATOR + affectedVnfc.getId()); + onapVnfc.setVimid(vimId); + notificationToSend.getAffectedVnfc().add(onapVnfc); + } + } + } + + private void addAffectedVirtualLinks(VnfLifecycleChangeNotification request, VNFLCMNotification notification) { + if (request.getAffectedVirtualLinks() != null) { + notification.setAffectedVl(new ArrayList<>()); + for (com.nokia.cbam.lcm.v32.model.AffectedVirtualLink affectedVirtualLink : request.getAffectedVirtualLinks()) { + org.onap.vnfmdriver.model.AffectedVirtualLink onapVirtualLink = new org.onap.vnfmdriver.model.AffectedVirtualLink(); + onapVirtualLink.setVlInstanceId(request.getVnfInstanceId() + SEPARATOR + affectedVirtualLink.getId()); + onapVirtualLink.setChangeType(getChangeType(affectedVirtualLink.getChangeType())); + onapVirtualLink.setVldid(affectedVirtualLink.getVirtualLinkDescId()); + AffectedVirtualLinkNetworkResource networkResource = new AffectedVirtualLinkNetworkResource(); + onapVirtualLink.setNetworkResource(networkResource); + networkResource.setResourceId(affectedVirtualLink.getResource().getResourceId()); + networkResource.setResourceType(AffectedVirtualLinkType.NETWORK); + notification.getAffectedVl().add(onapVirtualLink); + } + } + } + + private void addAffectedCps(String vimId, VNFLCMNotification notificationToSend, ReportedAffectedConnectionPoints affectedCps) { + if (affectedCps != null) { + notificationToSend.setAffectedCp(new ArrayList<>()); + for (ReportedAffectedCp affectedCp : affectedCps.getPost()) { + if (affectedCp.getCpdId() != null) { + AffectedCp onapAffectedCp = buildAffectedCp(vimId, notificationToSend.getVnfInstanceId(), affectedCp); + onapAffectedCp.setCpdid(affectedCp.getCpdId()); + notificationToSend.getAffectedCp().add(onapAffectedCp); + } + if (affectedCp.getEcpdId() != null) { + AffectedCp onapAffectedCp = buildAffectedCp(vimId, notificationToSend.getVnfInstanceId(), affectedCp); + onapAffectedCp.setCpdid(affectedCp.getEcpdId()); + notificationToSend.getAffectedCp().add(onapAffectedCp); + } + } + } + } + + private org.onap.vnfmdriver.model.OperationType getOperation(String vnfmId, String vnfId, OperationExecution operationExecution, com.nokia.cbam.lcm.v32.model.OperationType type, List<com.nokia.cbam.lcm.v32.model.AffectedVnfc> affectedVnfcs) { + switch (type) { + case TERMINATE: + return org.onap.vnfmdriver.model.OperationType.TERMINAL; + case INSTANTIATE: + return org.onap.vnfmdriver.model.OperationType.INSTANTIATE; + case SCALE: + ScaleVnfRequest originalRequest = new Gson().fromJson(new Gson().toJson(operationExecution.getOperationParams()), ScaleVnfRequest.class); + switch (originalRequest.getType()) { + case IN: + return org.onap.vnfmdriver.model.OperationType.SCALEIN; + default: //OUT + return org.onap.vnfmdriver.model.OperationType.SCALEOUT; + } + default: + return org.onap.vnfmdriver.model.OperationType.HEAL; + } + } + + private String extractServerName(Object additionalData) { + return new Gson().toJsonTree(additionalData).getAsJsonObject().get("name").getAsString(); + } + + private org.onap.vnfmdriver.model.VnfNotificationType getChangeType(com.nokia.cbam.lcm.v32.model.ChangeType changeType) { + switch (changeType) { + case ADDED: + return org.onap.vnfmdriver.model.VnfNotificationType.ADDED; + case REMOVED: + return org.onap.vnfmdriver.model.VnfNotificationType.REMOVED; + default: //case MODIFIED: + return org.onap.vnfmdriver.model.VnfNotificationType.MODIFIED; + } + } + +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcPackageProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcPackageProvider.java new file mode 100644 index 00000000..b8de2378 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcPackageProvider.java @@ -0,0 +1,107 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc; + +import com.google.common.io.ByteStreams; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import org.apache.http.HttpEntity; +import org.apache.http.HttpHeaders; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.api.IPackageProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.IpMappingProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfccatalog.api.VnfpackageApi; +import org.onap.vfccatalog.model.VnfPkgDetailInfo; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; + +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.CbamUtils.fatalFailure; +import static org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.util.SystemFunctions.systemFunctions; +import static org.slf4j.LoggerFactory.getLogger; +import static org.springframework.http.MediaType.APPLICATION_OCTET_STREAM_VALUE; + +/** + * Retrieves a package from VF-C + */ +@Component +@Conditional(value = Conditions.UseForVfc.class) +public class VfcPackageProvider implements IPackageProvider { + private static Logger logger = getLogger(VfcPackageProvider.class); + private final VfcRestApiProvider restApiProvider; + private final IpMappingProvider ipMappingProvider; + + @Autowired + VfcPackageProvider(VfcRestApiProvider restApiProvider, IpMappingProvider ipMappingProvider) { + this.restApiProvider = restApiProvider; + this.ipMappingProvider = ipMappingProvider; + } + + @Override + public String getCbamVnfdId(String csarId) { + try { + VnfpackageApi onapCatalogApi = restApiProvider.getOnapCatalogApi(); + VnfPkgDetailInfo vnfPackageDetails = onapCatalogApi.queryVnfPackage(csarId); + JsonElement vnfdModel = new JsonParser().parse(vnfPackageDetails.getPackageInfo().getVnfdModel()); + return vnfdModel.getAsJsonObject().get("metadata").getAsJsonObject().get("resourceVendorModelNumber").getAsString(); + } catch (Exception e) { + throw fatalFailure(logger, "Unable to query VNF package with " + csarId + " from VF-C", e); + } + } + + @Override + public byte[] getPackage(String csarId) { + String downloadUrl; + try { + VnfpackageApi onapCatalogApi = restApiProvider.getOnapCatalogApi(); + VnfPkgDetailInfo vnfPackageDetails = onapCatalogApi.queryVnfPackage(csarId); + downloadUrl = vnfPackageDetails.getPackageInfo().getDownloadUrl(); + String host = new URL(downloadUrl).getHost(); + if (!ipMappingProvider.mapPrivateIpToPublicIp(host).equals(host)) { + downloadUrl = downloadUrl.replaceFirst("://" + host, "://" + ipMappingProvider.mapPrivateIpToPublicIp(host)); + } + } catch (Exception e) { + throw fatalFailure(logger, "Unable to query VNF package with " + csarId + " from VF-C", e); + } + try { + return downloadCbamVnfPackage(downloadUrl); + } catch (Exception e) { + throw fatalFailure(logger, "Unable to download package from " + downloadUrl + " from VF-C", e); + } + } + + private byte[] downloadCbamVnfPackage(String downloadUri) throws IOException { + CloseableHttpClient client = systemFunctions().getHttpClient(); + HttpGet httpget = new HttpGet(downloadUri); + httpget.setHeader(HttpHeaders.ACCEPT, APPLICATION_OCTET_STREAM_VALUE); + CloseableHttpResponse response = client.execute(httpget); + HttpEntity entity = response.getEntity(); + InputStream is = entity.getContent(); + ByteArrayOutputStream cbamInZip = new ByteArrayOutputStream(); + byte[] bytes = ByteStreams.toByteArray(is); + client.close(); + return bytes; + } +} diff --git a/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcRestApiProvider.java b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcRestApiProvider.java new file mode 100644 index 00000000..fd4e6932 --- /dev/null +++ b/nokiav2/driver/src/main/java/org/onap/vfc/nfvo/driver/vnfm/svnfm/nokia/onap/vfc/VfcRestApiProvider.java @@ -0,0 +1,74 @@ +/* + * Copyright 2016-2017, Nokia Corporation + * + * 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.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.vfc; + +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.onap.core.MsbApiProvider; +import org.onap.vfc.nfvo.driver.vnfm.svnfm.nokia.spring.Conditions; +import org.onap.vfccatalog.api.VnfpackageApi; +import org.onap.vnfmdriver.api.NslcmApi; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Conditional; +import org.springframework.stereotype.Component; + +/** + * Responsible for providing access to VF-C REST APIs + */ +@Component +@Conditional(value = Conditions.UseForVfc.class) +public class VfcRestApiProvider { + static final String NSLCM_API_SERVICE_NAME = "nslcm"; + static final String NSLCM_API_VERION = "v1"; + static final String NSCATALOG_SERVICE_NAME = "catalog"; + static final String NSCATALOG_API_VERSION = "v1"; + private final MsbApiProvider msbApiProvider; + + @Autowired + VfcRestApiProvider(MsbApiProvider msbApiProvider) { + this.msbApiProvider = msbApiProvider; + } + + /** + * @return API to access VF-C for granting & LCN API + */ + public NslcmApi getNsLcmApi() { + org.onap.vnfmdriver.ApiClient apiClient = new org.onap.vnfmdriver.ApiClient(); + String correctedUrl = fixIncorrectUrl(); + apiClient.setBasePath(correctedUrl); + return new NslcmApi(apiClient); + } + + /** + * @return API to access VF-C catalog API + */ + public VnfpackageApi getOnapCatalogApi() { + org.onap.vfccatalog.ApiClient vfcApiClient = new org.onap.vfccatalog.ApiClient(); + vfcApiClient.setBasePath(msbApiProvider.getMicroServiceUrl(NSCATALOG_SERVICE_NAME, NSCATALOG_API_VERSION)); + return new VnfpackageApi(vfcApiClient); + } + + /** + * The swagger schema definition is not consistent with MSB info. The MSB reports + * the base path /restapi/nsclm/v1 (correct) and the paths defined in swagger is + * /nsclm/v1 making all API calls /restapi/nsclm/v1/nsclm/v1 (incorrect) + * + * @return + */ + private String fixIncorrectUrl() { + String urlInMsb = msbApiProvider.getMicroServiceUrl(NSLCM_API_SERVICE_NAME, NSLCM_API_VERION); + //FIXME in VF-C swagger API definitions + return urlInMsb.replaceFirst("/nslcm/v1", ""); + } +} |