diff options
Diffstat (limited to 'adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main')
5 files changed, 349 insertions, 0 deletions
diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiHelper.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiHelper.java index 893df02019..bacbea141e 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiHelper.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiHelper.java @@ -30,6 +30,8 @@ import org.onap.aai.domain.yang.Relationship; import org.onap.aai.domain.yang.RelationshipData; import org.onap.aai.domain.yang.RelationshipList; import org.onap.aai.domain.yang.Tenant; +import org.onap.aai.domain.yang.Vserver; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs; import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmNotFoundException; import org.onap.so.client.aai.AAIObjectType; import org.onap.so.client.aai.AAIVersion; @@ -172,4 +174,43 @@ public class AaiHelper { return false; } + /** + * Create a vserver. + * + * @param vnfc the VNFC to base the vserver on + * @return the vserver + */ + public Vserver createVserver(final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) { + final Vserver vserver = new Vserver(); + vserver.setVserverId(vnfc.getComputeResource().getResourceId()); + vserver.setVserverName(vnfc.getId()); + vserver.setProvStatus("active"); + vserver.setVserverSelflink("Not available"); + return vserver; + } + + /** + * Add a relationship to the given vserver to the given VNF. + * + * @param vnf the vserver + * @param vnfmId the ID of the VNF + */ + public void addRelationshipFromVserverVnfToGenericVnf(final Vserver vserver, final String vnfId) { + if (vserver.getRelationshipList() == null) { + vserver.setRelationshipList(new RelationshipList()); + } + final RelationshipList vserverRelationshiplist = vserver.getRelationshipList(); + vserverRelationshiplist.getRelationship().add(createRelationshipToGenericVnf(vnfId)); + } + + private Relationship createRelationshipToGenericVnf(final String vnfId) { + final Relationship relationship = new Relationship(); + relationship.setRelatedTo("generic-vnf"); + relationship.setRelationshipLabel("tosca.relationships.HostedOn"); + relationship.setRelatedLink("/aai/" + AAIVersion.LATEST + + AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNF, vnfId).build().toString()); + relationship.getRelationshipData().add(createRelationshipData("generic-vnf.vnf-id", vnfId)); + return relationship; + } + } diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProvider.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProvider.java index d11da0c91b..a043bb85b6 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProvider.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProvider.java @@ -20,11 +20,13 @@ package org.onap.so.adapters.vnfmadapter.extclients.aai; +import java.util.List; import org.onap.aai.domain.yang.EsrSystemInfoList; import org.onap.aai.domain.yang.EsrVnfm; import org.onap.aai.domain.yang.EsrVnfmList; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.Tenant; +import org.onap.aai.domain.yang.Vserver; /** * Provides methods for invoking REST calls to AAI. @@ -40,6 +42,14 @@ public interface AaiServiceProvider { GenericVnf invokeGetGenericVnf(final String vnfId); /** + * Invoke a query for a generic VNF with the given selfLink + * + * @param selfLink the selfLink + * @return the matching generic vnfs + */ + List<GenericVnf> invokeQueryGenericVnf(final String selfLink); + + /** * Invoke a GET request for the VNFMs. * * @return the VNFMs @@ -70,6 +80,18 @@ public interface AaiServiceProvider { void invokePutGenericVnf(GenericVnf vnf); /** + * Invoke a PUT request for a vserver. + * + * @param cloudOwner the cloud owner + * @param cloudRegion the cloud region + * @param tenantId the ID of the tenant + * @param vserver the vserver + * @return + */ + void invokePutVserver(final String cloudOwner, final String cloudRegion, final String tenantId, + final Vserver vserver); + + /** * Invoke a GET request for the a tenant. * * @param cloudOwner the cloud owner diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProviderImpl.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProviderImpl.java index fa0dcf07f1..364a6415a8 100644 --- a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProviderImpl.java +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/extclients/aai/AaiServiceProviderImpl.java @@ -20,11 +20,13 @@ package org.onap.so.adapters.vnfmadapter.extclients.aai; +import java.util.List; import org.onap.aai.domain.yang.EsrSystemInfoList; import org.onap.aai.domain.yang.EsrVnfm; import org.onap.aai.domain.yang.EsrVnfmList; import org.onap.aai.domain.yang.GenericVnf; import org.onap.aai.domain.yang.Tenant; +import org.onap.aai.domain.yang.Vserver; import org.onap.so.client.aai.AAIObjectType; import org.onap.so.client.aai.entities.uri.AAIUriFactory; import org.slf4j.Logger; @@ -54,6 +56,17 @@ public class AaiServiceProviderImpl implements AaiServiceProvider { } @Override + public List<GenericVnf> invokeQueryGenericVnf(final String selfLink) { + return aaiClientProvider.getAaiClient() + .get(List.class, + AAIUriFactory.createResourceUri(AAIObjectType.GENERIC_VNFS).queryParam("selflink", selfLink)) + .orElseGet(() -> { + logger.debug("No vnf found in AAI with selflink: {}", selfLink); + return null; + }); + } + + @Override public EsrVnfmList invokeGetVnfms() { return aaiClientProvider.getAaiClient() .get(EsrVnfmList.class, AAIUriFactory.createResourceUri(AAIObjectType.VNFM_LIST)).orElseGet(() -> { @@ -89,6 +102,13 @@ public class AaiServiceProviderImpl implements AaiServiceProvider { } @Override + public void invokePutVserver(final String cloudOwner, final String cloudRegion, final String tenant, + final Vserver vserver) { + aaiClientProvider.getAaiClient().update(AAIUriFactory.createResourceUri(AAIObjectType.VSERVER, cloudOwner, + cloudRegion, tenant, vserver.getVserverId()), vserver); + } + + @Override public Tenant invokeGetTenant(final String cloudOwner, final String cloudRegion, final String tenantId) { return aaiClientProvider.getAaiClient() .get(Tenant.class, diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java new file mode 100644 index 0000000000..36b197dd06 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/notificationhandling/NotificationHandler.java @@ -0,0 +1,159 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.vnfmadapter.notificationhandling; + +import static org.slf4j.LoggerFactory.getLogger; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.json.JSONException; +import org.json.JSONObject; +import org.onap.aai.domain.yang.GenericVnf; +import org.onap.aai.domain.yang.Vserver; +import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper; +import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201VimConnectionInfo; +import org.slf4j.Logger; + +/** + * Performs updates to AAI based on a received notification. The updates are executed in a separate + * thread so as the notification response to the VNFM is not delayed. + */ +public class NotificationHandler implements Runnable { + private static Logger logger = getLogger(NotificationHandler.class); + private final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification; + private final AaiHelper aaiHelper; + private final AaiServiceProvider aaiServiceProvider; + + + private final InlineResponse201 vnfInstance; + + public NotificationHandler(final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification, + final AaiHelper aaiHelper, final AaiServiceProvider aaiServiceProvider, + final InlineResponse201 vnfInstance) { + this.vnfLcmOperationOccurrenceNotification = vnfLcmOperationOccurrenceNotification; + this.aaiHelper = aaiHelper; + this.aaiServiceProvider = aaiServiceProvider; + this.vnfInstance = vnfInstance; + } + + @Override + public void run() { + try { + if (vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) { + final GenericVnf genericVnf = + aaiServiceProvider.invokeQueryGenericVnf(vnfInstance.getLinks().getSelf().getHref()).get(0); + + switch (vnfLcmOperationOccurrenceNotification.getOperation()) { + case INSTANTIATE: + handleVnfInstantiated(genericVnf); + break; + default: + } + } + } catch (final Exception exception) { + logger.error("Error encountered handling notification, AAI may not be updated correctly " + + vnfLcmOperationOccurrenceNotification, exception); + } + } + + private void handleVnfInstantiated(final GenericVnf genericVnf) { + final String ipAddress = getOamIpAddress(vnfInstance); + logger.debug("Updating " + genericVnf.getVnfId() + " with VNF OAM IP ADDRESS: " + ipAddress); + genericVnf.setIpv4OamAddress(ipAddress); + genericVnf.setOrchestrationStatus("Created"); + + aaiServiceProvider.invokePutGenericVnf(genericVnf); + + updateVservers(vnfLcmOperationOccurrenceNotification, genericVnf.getVnfId(), + vnfInstance.getVimConnectionInfo()); + + logger.debug("Finished handling notification for vnfm: " + vnfInstance.getId()); + } + + private String getOamIpAddress(final InlineResponse201 vnfInstance) { + try { + logger.debug("ConfigurableProperties: " + vnfInstance.getVnfConfigurableProperties()); + if (vnfInstance.getVnfConfigurableProperties() == null) { + logger.warn("No ConfigurableProperties, cannot set OAM IP Address"); + return null; + } + final JSONObject properties = new JSONObject((Map) vnfInstance.getVnfConfigurableProperties()); + return properties.get("vnfIpAddress").toString(); + } catch (final JSONException jsonException) { + logger.error("Error getting vnfIpAddress", jsonException); + return null; + } + } + + private void updateVservers(final VnfLcmOperationOccurrenceNotification notification, final String vnfId, + final List<InlineResponse201VimConnectionInfo> vnfInstancesVimConnectionInfo) { + final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo = new HashMap<>(); + for (final InlineResponse201VimConnectionInfo vimConnectionInfo : vnfInstancesVimConnectionInfo) { + vimConnectionIdToVimConnectionInfo.put(vimConnectionInfo.getId(), vimConnectionInfo); + } + + for (final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc : notification.getAffectedVnfcs()) { + + switch (vnfc.getChangeType()) { + case ADDED: + final Vserver vserver = aaiHelper.createVserver(vnfc); + aaiHelper.addRelationshipFromVserverVnfToGenericVnf(vserver, vnfId); + final InlineResponse201VimConnectionInfo vimConnectionInfo = + getVimConnectionInfo(vimConnectionIdToVimConnectionInfo, vnfc); + aaiServiceProvider.invokePutVserver(getCloudOwner(vimConnectionInfo), + getCloudRegion(vimConnectionInfo), getTenant(vimConnectionInfo), vserver); + break; + case REMOVED: + case MODIFIED: + case TEMPORARY: + default: + } + } + } + + private InlineResponse201VimConnectionInfo getVimConnectionInfo( + final Map<String, InlineResponse201VimConnectionInfo> vimConnectionIdToVimConnectionInfo, + final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc) { + final String vimConnectionId = vnfc.getComputeResource().getVimConnectionId(); + return vimConnectionIdToVimConnectionInfo.get(vimConnectionId); + } + + private String getCloudOwner(final InlineResponse201VimConnectionInfo vimConnectionInfo) { + final String vimId = vimConnectionInfo.getVimId(); + return vimId.substring(0, vimId.indexOf("_")); + } + + private String getCloudRegion(final InlineResponse201VimConnectionInfo vimConnectionInfo) { + final String vimId = vimConnectionInfo.getVimId(); + return vimId.substring(vimId.indexOf("_") + 1); + } + + private String getTenant(final InlineResponse201VimConnectionInfo vimConnectionInfo) { + final JSONObject vimConnectionJsonObject = new JSONObject(vimConnectionInfo); + return vimConnectionJsonObject.getJSONObject("accessInfo").get("projectId").toString(); + } + +} diff --git a/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java new file mode 100644 index 0000000000..60f3f51e52 --- /dev/null +++ b/adapters/mso-vnfm-adapter/mso-vnfm-etsi-adapter/src/main/java/org/onap/so/adapters/vnfmadapter/rest/Sol003LcnContoller.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * Copyright (C) 2019 Nordix Foundation. + * ================================================================================ + * 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. + * + * SPDX-License-Identifier: Apache-2.0 + * ============LICENSE_END========================================================= + */ + +package org.onap.so.adapters.vnfmadapter.rest; + +import static org.onap.so.adapters.vnfmadapter.Constants.BASE_URL; +import static org.slf4j.LoggerFactory.getLogger; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import javax.ws.rs.core.MediaType; +import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiHelper; +import org.onap.so.adapters.vnfmadapter.extclients.aai.AaiServiceProvider; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfIdentifierCreationNotification; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfIdentifierDeletionNotification; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum; +import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201; +import org.onap.so.adapters.vnfmadapter.notificationhandling.NotificationHandler; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * Controller for handling notifications from the VNFM (Virtual Network Function Manager). + */ +@Controller +@RequestMapping(value = BASE_URL, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}, + consumes = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) +public class Sol003LcnContoller { + private static Logger logger = getLogger(Sol003LcnContoller.class); + private static final String LOG_LCN_RECEIVED = "LCN received from VNFM: "; + private final AaiServiceProvider aaiServiceProvider; + private final AaiHelper aaiHelper; + private final VnfmServiceProvider vnfmServiceProvider; + private final ExecutorService executor = Executors.newCachedThreadPool(); + + @Autowired + Sol003LcnContoller(final AaiServiceProvider aaiServiceProvider, final AaiHelper aaiHelper, + final VnfmServiceProvider vnfmServiceProvider) { + this.aaiServiceProvider = aaiServiceProvider; + this.aaiHelper = aaiHelper; + this.vnfmServiceProvider = vnfmServiceProvider; + } + + @PostMapping(value = "/lcn/VnfIdentifierCreationNotification") + public ResponseEntity<Void> lcnVnfIdentifierCreationNotificationPost( + @RequestBody final VnfIdentifierCreationNotification vnfIdentifierCreationNotification) { + logger.info(LOG_LCN_RECEIVED + vnfIdentifierCreationNotification); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @PostMapping(value = "/lcn/VnfIdentifierDeletionNotification") + public ResponseEntity<Void> lcnVnfIdentifierDeletionNotificationPost( + @RequestBody final VnfIdentifierDeletionNotification vnfIdentifierDeletionNotification) { + logger.info(LOG_LCN_RECEIVED + vnfIdentifierDeletionNotification); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + @PostMapping(value = "/lcn/VnfLcmOperationOccurrenceNotification") + public ResponseEntity<Void> lcnVnfLcmOperationOccurrenceNotificationPost( + @RequestBody final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification) { + logger.info(LOG_LCN_RECEIVED + vnfLcmOperationOccurrenceNotification); + + final OperationEnum operation = vnfLcmOperationOccurrenceNotification.getOperation(); + if ((operation.equals(OperationEnum.INSTANTIATE)) + && vnfLcmOperationOccurrenceNotification.getOperationState().equals(OperationStateEnum.COMPLETED)) { + final InlineResponse201 vnfInstance = getVnfInstance(vnfLcmOperationOccurrenceNotification); + final NotificationHandler handler = new NotificationHandler(vnfLcmOperationOccurrenceNotification, + aaiHelper, aaiServiceProvider, vnfInstance); + executor.execute(handler); + } + + logger.info("Sending notification response"); + return new ResponseEntity<>(HttpStatus.NO_CONTENT); + } + + private InlineResponse201 getVnfInstance( + final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification) { + return vnfmServiceProvider.getVnf(vnfLcmOperationOccurrenceNotification.getLinks().getVnfInstance().getHref()) + .get(); + } + +} |