public static final String SERVICE_NAME = "vnfm-adapter";
public static final String SERVICE_VERSION = "v1";
public static final String BASE_URL = "/so/" + SERVICE_NAME + "/" + SERVICE_VERSION;
+ public static final String OPERATION_NOTIFICATION_ENDPOINT = "/lcn/VnfLcmOperationOccurrenceNotification";
private Constants() {}
}
package org.onap.so.adapters.vnfmadapter.extclients.vnfm;
+import static org.onap.so.adapters.vnfmadapter.Constants.BASE_URL;
+import static org.onap.so.adapters.vnfmadapter.Constants.OPERATION_NOTIFICATION_ENDPOINT;
import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import org.onap.so.adapters.vnfmadapter.extclients.vim.model.InterfaceInfo;
import org.onap.so.adapters.vnfmadapter.extclients.vim.model.VimCredentials;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthentication.AuthTypeEnum;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilter.NotificationTypesEnum;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsFilterVnfInstanceSubscriptionFilter;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.VnfInstancesvnfInstanceIdinstantiateExtVirtualLinks;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.VnfInstancesvnfInstanceIdinstantiateVimConnectionInfo;
+import org.onap.so.security.WebSecurityConfig;
import org.onap.vnfmadapter.v1.model.CreateVnfRequest;
import org.onap.vnfmadapter.v1.model.ExternalVirtualLink;
import org.onap.vnfmadapter.v1.model.Tenant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
/**
private static final Logger logger = LoggerFactory.getLogger(VnfmHelper.class);
private static final String SEPARATOR = "_";
private final AaiServiceProvider aaiServiceProvider;
+ private final WebSecurityConfig webSecurityConfig;
+
+ @Value("${vnfmadapter.endpoint}")
+ private String vnfmAdapterEndoint;
@Autowired
- public VnfmHelper(final AaiServiceProvider aaiServiceProvider) {
+ public VnfmHelper(final AaiServiceProvider aaiServiceProvider, final WebSecurityConfig webSecurityConfig) {
this.aaiServiceProvider = aaiServiceProvider;
+ this.webSecurityConfig = webSecurityConfig;
}
/**
return null;
}
+ /**
+ * Create a {@link LccnSubscriptionRequest} to send in an notification subscription request to a
+ * VNFM.
+ *
+ * @param the ID of the VNF notifications are required for
+ *
+ * @return the request
+ */
+ public LccnSubscriptionRequest createNotificationSubscriptionRequest(final String vnfId) {
+ final LccnSubscriptionRequest lccnSubscriptionRequest = new LccnSubscriptionRequest();
+ lccnSubscriptionRequest.setAuthentication(getSubscriptionsAuthentication());
+ lccnSubscriptionRequest.setCallbackUri(vnfmAdapterEndoint + BASE_URL + OPERATION_NOTIFICATION_ENDPOINT);
+ final SubscriptionsFilter filter = new SubscriptionsFilter();
+ filter.addNotificationTypesItem(NotificationTypesEnum.VNFLCMOPERATIONOCCURRENCENOTIFICATION);
+ final SubscriptionsFilterVnfInstanceSubscriptionFilter vnfInstanceSubscriptionFilter =
+ new SubscriptionsFilterVnfInstanceSubscriptionFilter();
+ vnfInstanceSubscriptionFilter.addVnfInstanceIdsItem(vnfId);
+ filter.setVnfInstanceSubscriptionFilter(vnfInstanceSubscriptionFilter);
+ lccnSubscriptionRequest.setFilter(filter);
+ return lccnSubscriptionRequest;
+ }
+
+ private SubscriptionsAuthentication getSubscriptionsAuthentication() {
+ final SubscriptionsAuthenticationParamsBasic basicAuthParams = new SubscriptionsAuthenticationParamsBasic();
+ basicAuthParams.setUserName("vnfm");
+ basicAuthParams.setPassword(webSecurityConfig.getUsercredentials().stream()
+ .filter(userCredentials -> "vnfm".equals(userCredentials.getUsername())).findFirst().get()
+ .getPassword());
+
+ final SubscriptionsAuthentication authentication = new SubscriptionsAuthentication();
+ authentication.addAuthTypeItem(AuthTypeEnum.BASIC);
+ authentication.paramsBasic(basicAuthParams);
+ return authentication;
+ }
+
}
import com.google.common.base.Optional;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
/**
*/
String instantiateVnf(final String vnfSelfLink, final InstantiateVnfRequest instantiateVnfRequest);
+ /**
+ * Invoke a notification subscription request to a VNFM.
+ *
+ * @param vnfmId the ID of the VNFM
+ * @param subscriptionRequest
+ * @return the response to the subscription request
+ */
+ InlineResponse2001 subscribeForNotifications(final String vnfmId,
+ final LccnSubscriptionRequest subscriptionRequest);
+
/**
* Invoke a terminate request for a VNF.
*
import com.google.common.base.Optional;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmRequestFailureException;
import org.onap.so.rest.service.HttpRestServiceProvider;
}
final String locationHeader = response.getHeaders().get("Location").iterator().next();
return locationHeader.substring(locationHeader.lastIndexOf("/") + 1);
+ }
+
+ @Override
+ public InlineResponse2001 subscribeForNotifications(final String vnfmId,
+ final LccnSubscriptionRequest subscriptionRequest) {
+ final String url = urlProvider.getSubscriptionsUrl(vnfmId);
+ ResponseEntity<InlineResponse2001> response = null;
+ try {
+ response = httpServiceProvider.postHttpRequest(subscriptionRequest, url, InlineResponse2001.class);
+ } catch (final Exception exception) {
+ final String errorMessage =
+ "Subscription to VNFM " + vnfmId + " resulted in exception" + subscriptionRequest;
+ logger.error(errorMessage, exception);
+ throw new VnfmRequestFailureException(errorMessage, exception);
+ }
+ if (response.getStatusCode() != HttpStatus.OK) {
+ final String errorMessage = "Subscription to VNFM " + vnfmId + " returned status code: "
+ + response.getStatusCode() + ", request: " + subscriptionRequest;
+ logger.error(errorMessage);
+ throw new VnfmRequestFailureException(errorMessage);
+ }
+ return response.getBody();
}
@Override
return url;
}
+ /**
+ * Get the URL for the subscriptions on a VNFM.
+ *
+ * @param vnfmId The ID of the VNFM
+ * @return the URL of the subscriptions
+ */
+ public String getSubscriptionsUrl(final String vnfmId) {
+ final String url =
+ UriComponentsBuilder.fromUri(getBaseUri(vnfmId)).pathSegment("/subscriptions").build().toString();
+ logger.debug("getOperationUrl:" + url);
+
+ return url;
+ }
+
private URI getBaseUri(final String vnfmId) {
final EsrSystemInfoList vnfmEsrSystemInfoList = aaiServiceProvider.invokeGetVnfmEsrSystemInfoList(vnfmId);
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.VnfmServiceProvider;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InstantiateVnfRequest;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.LccnSubscriptionRequest;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.TerminateVnfRequest.TerminationTypeEnum;
import org.onap.so.adapters.vnfmadapter.jobmanagement.JobManager;
}
final String vnfIdInVnfm = sendCreateRequestToVnfm(genericVnf);
+ createNotificationSubscription(vnfm.getVnfmId(), vnfIdInVnfm);
final String operationId = sendInstantiateRequestToVnfm(vnfm, genericVnf, request, vnfIdInAai, vnfIdInVnfm);
final String jobId = jobManager.createJob(vnfm.getVnfmId(), operationId, false);
return "vnfId";
}
+ private void createNotificationSubscription(final String vnfmId, final String vnfId) {
+ try {
+ final LccnSubscriptionRequest subscriptionRequest = vnfmHelper.createNotificationSubscriptionRequest(vnfId);
+ vnfmServiceProvider.subscribeForNotifications(vnfmId, subscriptionRequest);
+ } catch (final Exception exception) {
+ logger.warn("Subscription for notifications to VNFM: " + vnfmId + " for VNF " + vnfId
+ + " failed. AAI will not be updated unless the VNFM is configured by other means to send notifications relating to this VNF",
+ exception);
+ }
+ }
+
private String sendInstantiateRequestToVnfm(final EsrVnfm vnfm, final GenericVnf genericVnf,
final CreateVnfRequest createVnfRequest, final String vnfIdInAai, final String vnfIdInVnfm) {
package org.onap.so.adapters.vnfmadapter.rest;
import static org.onap.so.adapters.vnfmadapter.Constants.BASE_URL;
+import static org.onap.so.adapters.vnfmadapter.Constants.OPERATION_NOTIFICATION_ENDPOINT;
import static org.slf4j.LoggerFactory.getLogger;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
- @PostMapping(value = "/lcn/VnfLcmOperationOccurrenceNotification")
+ @PostMapping(value = OPERATION_NOTIFICATION_ENDPOINT)
public ResponseEntity<Void> lcnVnfLcmOperationOccurrenceNotificationPost(
@RequestBody final VnfLcmOperationOccurrenceNotification vnfLcmOperationOccurrenceNotification) {
logger.info(LOG_LCN_RECEIVED + vnfLcmOperationOccurrenceNotification);
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;
import static org.onap.so.client.RestTemplateConfig.CONFIGURABLE_REST_TEMPLATE;
+import static org.springframework.test.web.client.match.MockRestRequestMatchers.content;
import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo;
+import static org.springframework.test.web.client.response.MockRestResponseCreators.withBadRequest;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withStatus;
import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess;
import com.google.gson.Gson;
import org.onap.aai.domain.yang.RelationshipList;
import org.onap.so.adapters.vnfmadapter.VnfmAdapterApplication;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
+import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse2001;
import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201;
import org.onap.so.adapters.vnfmadapter.rest.exceptions.VnfmNotFoundException;
import org.onap.so.client.aai.AAIResourcesClient;
setUpVnfmsInMockAai();
setUpVimInMockAai();
+ final String expectedsubscriptionRequest =
+ "{\"filter\":{\"vnfInstanceSubscriptionFilter\":{\"vnfInstanceIds\":[\"vnfId\"]},\"notificationTypes\":[\"VnfLcmOperationOccurrenceNotification\"]},\"callbackUri\":\"https://so-vnfm-adapter.onap:30406/so/vnfm-adapter/v1/lcn/VnfLcmOperationOccurrenceNotification\",\"authentication\":{\"authType\":[\"BASIC\"],\"paramsBasic\":{\"userName\":\"vnfm\",\"password\":\"$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke\"}}}";
+ final InlineResponse2001 subscriptionResponse = new InlineResponse2001();
+ mockRestServer.expect(requestTo("http://vnfm2:8080/subscriptions"))
+ .andExpect(content().json(expectedsubscriptionRequest))
+ .andRespond(withSuccess(gson.toJson(subscriptionResponse), MediaType.APPLICATION_JSON));
+
mockRestServer.expect(requestTo("http://dummy.value/until/create/implememted/vnfId/instantiate"))
.andRespond(withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
.location(new URI("http://vnfm2:8080/vnf_lcm_op_occs/123456")));
setUpVnfmsInMockAai();
setUpVimInMockAai();
+ mockRestServer.expect(requestTo("http://vnfm2:8080/subscriptions")).andRespond(withBadRequest());
+
mockRestServer.expect(requestTo("http://dummy.value/until/create/implememted/vnfId/instantiate"))
.andRespond(withStatus(HttpStatus.ACCEPTED).contentType(MediaType.APPLICATION_JSON)
.location(new URI("http://vnfm2:8080/vnf_lcm_op_occs/123456")));
- username: test
password: '$2a$12$Zi3AuYcZoZO/gBQyUtST2.F5N6HqcTtaNci2Et.ufsQhski56srIu'
role: BPEL-Client
+ - username: vnfm
+ password: '$2a$10$Fh9ffgPw2vnmsghsRD3ZauBL1aKXebigbq3BB1RPWtE62UDILsjke'
+ role: BPEL-Client
mso:
key: 07a7159d3bf51a0e53be7a8f89699be7
aai:
auth: 2A11B07DB6214A839394AA1EC5844695F5114FC407FF5422625FB00175A3DCB8A1FF745F22867EFA72D5369D599BBD88DA8BED4233CF5586
endpoint: https://aai.onap:8443
- version: v15
\ No newline at end of file
+ version: v15
+
+vnfmadapter:
+ endpoint: https://so-vnfm-adapter.onap:30406
\ No newline at end of file