1 package org.onap.svnfm.simulator.services;
3 import com.google.gson.JsonObject;
4 import com.google.gson.JsonParser;
5 import java.io.BufferedReader;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
10 import java.nio.charset.StandardCharsets;
11 import java.util.ArrayList;
12 import java.util.List;
13 import java.util.UUID;
14 import javax.net.ssl.HttpsURLConnection;
15 import javax.ws.rs.core.MediaType;
16 import org.apache.commons.codec.binary.Base64;
17 import org.modelmapper.ModelMapper;
18 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiResponse;
19 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest;
20 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsAddResources;
21 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinks;
22 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinksVnfLcmOpOcc;
23 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201;
24 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiClient;
25 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiException;
26 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.api.DefaultApi;
27 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs;
28 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum;
29 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks;
30 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationStatusEnum;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationTypeEnum;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationEnum;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo;
38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
39 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
40 import org.onap.svnfm.simulator.config.ApplicationConfig;
41 import org.onap.svnfm.simulator.model.VnfOperation;
42 import org.onap.svnfm.simulator.model.Vnfds;
43 import org.onap.svnfm.simulator.repository.VnfOperationRepository;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46 import org.springframework.core.io.ClassPathResource;
48 public abstract class OperationProgressor implements Runnable {
50 private static final Logger LOGGER = LoggerFactory.getLogger(OperationProgressor.class);
51 private static final String CERTIFICATE_TO_TRUST = "so-vnfm-adapter.crt.pem";
53 protected final VnfOperation operation;
54 protected final SvnfmService svnfmService;
55 private final VnfOperationRepository vnfOperationRepository;
56 private final ApplicationConfig applicationConfig;
57 protected final Vnfds vnfds;
58 private final SubscriptionService subscriptionService;
59 private final DefaultApi notificationClient;
60 private final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi grantClient;
62 public OperationProgressor(final VnfOperation operation, final SvnfmService svnfmService,
63 final VnfOperationRepository vnfOperationRepository, final ApplicationConfig applicationConfig,
64 final Vnfds vnfds, final SubscriptionService subscriptionService) {
65 this.operation = operation;
66 this.svnfmService = svnfmService;
67 this.vnfOperationRepository = vnfOperationRepository;
68 this.applicationConfig = applicationConfig;
70 this.subscriptionService = subscriptionService;
72 final ApiClient apiClient = new ApiClient();
73 String callBackUrl = subscriptionService.getSubscriptions().iterator().next().getCallbackUri();
74 callBackUrl = callBackUrl.substring(0, callBackUrl.indexOf("/lcn/"));
75 apiClient.setBasePath(callBackUrl);
76 apiClient.setSslCaCert(getCertificateToTrust());
77 notificationClient = new DefaultApi(apiClient);
79 final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient grantApiClient =
80 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient();
81 grantApiClient.setBasePath(callBackUrl);
82 grantApiClient.setSslCaCert(getCertificateToTrust());
83 grantClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi(grantApiClient);
86 private InputStream getCertificateToTrust() {
88 return new ClassPathResource(CERTIFICATE_TO_TRUST).getInputStream();
89 } catch (final IOException exception) {
90 LOGGER.error("Error reading certificate to trust, https calls to VNFM adapter will fail", exception);
98 final VnfLcmOperationOccurrenceNotification notificationOfStarting =
99 buildNotification(NotificationStatusEnum.START, OperationStateEnum.STARTING);
100 sendNotification(notificationOfStarting);
103 setState(InlineResponse200.OperationStateEnum.PROCESSING);
104 final VnfLcmOperationOccurrenceNotification notificationOfProcessing =
105 buildNotification(NotificationStatusEnum.START, OperationStateEnum.PROCESSING);
106 sendNotification(notificationOfProcessing);
109 final GrantRequest grantRequest = buildGrantRequest();
110 final InlineResponse201 grantResponse = sendGrantRequest(grantRequest);
111 final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> vnfcs = handleGrantResponse(grantResponse);
113 svnfmService.getVnf(operation.getVnfInstanceId()).getInstantiatedVnfInfo();
116 setState(InlineResponse200.OperationStateEnum.COMPLETED);
117 final VnfLcmOperationOccurrenceNotification notificationOfCompleted =
118 buildNotification(NotificationStatusEnum.RESULT, OperationStateEnum.COMPLETED);
119 notificationOfCompleted.setAffectedVnfcs(getVnfcs(vnfcs));
121 sendNotification(notificationOfCompleted);
122 } catch (final Exception exception) {
123 LOGGER.error("Error in OperationProgressor ", exception);
128 private void sleep(final long milliSeconds) {
130 Thread.sleep(milliSeconds);
131 } catch (final InterruptedException e) {
132 operation.setOperationState(InlineResponse200.OperationStateEnum.FAILED);
133 // Restore interrupted state
134 Thread.currentThread().interrupt();
138 private void setState(final InlineResponse200.OperationStateEnum state) {
139 LOGGER.info("Setting state to {} for operation {}", state, operation.getId());
140 operation.setOperationState(state);
141 vnfOperationRepository.save(operation);
144 private VnfLcmOperationOccurrenceNotification buildNotification(final NotificationStatusEnum status,
145 final OperationStateEnum operationState) {
146 final VnfLcmOperationOccurrenceNotification notification = new VnfLcmOperationOccurrenceNotification();
147 notification.setId(UUID.randomUUID().toString());
148 notification.setNotificationType(NotificationTypeEnum.VNFLCMOPERATIONOCCURRENCENOTIFICATION);
149 notification.setNotificationStatus(status);
150 notification.setOperationState(operationState);
151 notification.setOperation(OperationEnum.fromValue(operation.getOperation().toString()));
152 notification.setVnfInstanceId(operation.getVnfInstanceId());
153 notification.setVnfLcmOpOccId(operation.getId());
155 final LcnVnfLcmOperationOccurrenceNotificationLinks links = new LcnVnfLcmOperationOccurrenceNotificationLinks();
156 final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance vnfInstanceLink =
157 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
158 vnfInstanceLink.setHref(getVnfLink());
159 links.setVnfInstance(vnfInstanceLink);
162 final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance operationLink =
163 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
164 operationLink.setHref(getOperationLink());
165 links.setVnfLcmOpOcc(operationLink);
167 notification.setLinks(links);
172 private List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> getVnfcs(
173 final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> instantiatedVnfcs) {
174 final List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> vnfcs = new ArrayList<>();
175 if (instantiatedVnfcs != null) {
176 for (final InlineResponse201InstantiatedVnfInfoVnfcResourceInfo instantiatedVnfc : instantiatedVnfcs) {
177 LOGGER.info("VNFC TO BE CONVERTED: {}", instantiatedVnfc);
178 final ModelMapper mapper = new ModelMapper();
179 final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc =
180 mapper.map(instantiatedVnfc, LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.class);
181 LOGGER.info("VNFC FROM CONVERSION: {}", vnfc);
182 vnfc.setChangeType(getVnfcChangeType());
189 private void sendNotification(final VnfLcmOperationOccurrenceNotification notification) {
190 LOGGER.info("Sending notification: {}", notification);
192 final SubscriptionsAuthenticationParamsBasic subscriptionAuthentication =
193 subscriptionService.getSubscriptions().iterator().next().getAuthentication().getParamsBasic();
195 subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword();
196 final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
197 String authHeader = "Basic " + new String(encodedAuth);
199 notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification,
200 MediaType.APPLICATION_JSON, authHeader);
201 } catch (final ApiException exception) {
202 LOGGER.error("Error sending notification: " + notification, exception);
203 LOGGER.error("Response code: {}, body: {}, basePath: {}", exception.getCode(), exception.getResponseBody(),
204 notificationClient.getApiClient().getBasePath());
210 public GrantRequest buildGrantRequest() {
211 final GrantRequest grantRequest = new GrantRequest();
212 grantRequest.setVnfInstanceId(operation.getVnfInstanceId());
213 final String vnfdId = svnfmService.getVnf(operation.getVnfInstanceId()).getVnfdId();
214 grantRequest.setVnfdId(vnfdId);
215 grantRequest.setAddResources(getAddResources(vnfdId));
216 grantRequest.setRemoveResources(getRemoveResources(vnfdId));
217 grantRequest.setVnfLcmOpOccId(operation.getId());
219 .setOperation(org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest.OperationEnum
220 .fromValue(operation.getOperation().getValue()));
221 grantRequest.setIsAutomaticInvocation(false);
223 final GrantsLinksVnfLcmOpOcc vnfInstanceLink = new GrantsLinksVnfLcmOpOcc();
224 vnfInstanceLink.setHref(getVnfLink());
225 final GrantsLinksVnfLcmOpOcc operationInstanceLink = new GrantsLinksVnfLcmOpOcc();
226 operationInstanceLink.setHref(getOperationLink());
227 final GrantsLinks links = new GrantsLinks();
228 links.setVnfInstance(vnfInstanceLink);
229 links.setVnfLcmOpOcc(operationInstanceLink);
230 grantRequest.setLinks(links);
234 protected abstract List<GrantsAddResources> getAddResources(final String vnfdId);
236 protected abstract List<GrantsAddResources> getRemoveResources(final String vnfdId);
238 protected abstract List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> handleGrantResponse(
239 InlineResponse201 grantResponse);
241 protected abstract ChangeTypeEnum getVnfcChangeType();
243 private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) {
244 LOGGER.info("Sending grant request: {}", grantRequest);
247 final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication =
248 subscriptionService.getSubscriptions().iterator().next().getAuthentication()
249 .getParamsOauth2ClientCredentials();
250 final String authHeader =
251 "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication);
253 final ApiResponse<InlineResponse201> response = grantClient.grantsPostWithHttpInfo(grantRequest,
254 MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader);
255 LOGGER.info("Grant Response: {}", response);
256 return response.getData();
257 } catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) {
258 LOGGER.error("Error sending notification: " + grantRequest, exception);
263 private String getVnfLink() {
264 return getLinkBaseUrl() + "/vnf_instances/" + operation.getVnfInstanceId();
267 private String getOperationLink() {
268 return getLinkBaseUrl() + "/vnf_lcm_op_occs/" + operation.getId();
271 private String getLinkBaseUrl() {
272 return applicationConfig.getBaseUrl() + "/vnflcm/v1";
275 private String getToken(final ApiClient apiClient,
276 final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
277 final String basePath = apiClient.getBasePath().substring(0, apiClient.getBasePath().indexOf("/so/"));
278 final String tokenUrl = basePath + "/oauth/token?grant_type=client_credentials";
281 URL url = new URL(tokenUrl);
282 HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
283 connection.setRequestMethod("POST");
284 final String authorizationHeader = getAuthorizationHeader(oauthClientCredentials);
285 connection.addRequestProperty("Authorization", authorizationHeader);
287 connection.connect();
289 return getResponse(connection).get("access_token").getAsString();
291 } catch (IOException exception) {
292 LOGGER.error("Error getting token", exception);
297 private String getAuthorizationHeader(
298 final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
299 final String auth = oauthClientCredentials.getClientId() + ":" + oauthClientCredentials.getClientPassword();
300 final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
301 return "Basic " + new String(encodedAuth);
304 private JsonObject getResponse(HttpsURLConnection connection) throws IOException {
305 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
306 String line, data = "";
307 while ((line = in.readLine()) != null) {
311 connection.getInputStream().close();
313 JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();