487a931c22e447b4ff140a013a181cdb8ec1abde
[integration/csit.git] / plans / so / integration-etsi-testing / so-simulators / vnfm-simulator / vnfm-service / src / main / java / org / onap / so / svnfm / simulator / services / OperationProgressor.java
1 package org.onap.so.svnfm.simulator.services;
2
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;
9 import java.net.URL;
10 import java.nio.charset.StandardCharsets;
11 import java.security.KeyStore;
12 import java.security.KeyStoreException;
13 import java.security.NoSuchAlgorithmException;
14 import java.security.UnrecoverableKeyException;
15 import java.security.cert.CertificateException;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.UUID;
19 import javax.net.ssl.HttpsURLConnection;
20 import javax.net.ssl.KeyManager;
21 import javax.net.ssl.KeyManagerFactory;
22 import javax.ws.rs.core.MediaType;
23 import org.apache.commons.codec.binary.Base64;
24 import org.modelmapper.ModelMapper;
25 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiResponse;
26 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest;
27 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsAddResources;
28 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinks;
29 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantsLinksVnfLcmOpOcc;
30 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.InlineResponse201;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiClient;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.ApiException;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.api.DefaultApi;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.ChangeTypeEnum;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinks;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance;
38 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification;
39 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationStatusEnum;
40 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.NotificationTypeEnum;
41 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationEnum;
42 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.lcn.model.VnfLcmOperationOccurrenceNotification.OperationStateEnum;
43 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse200;
44 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.InlineResponse201InstantiatedVnfInfoVnfcResourceInfo;
45 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsBasic;
46 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.model.SubscriptionsAuthenticationParamsOauth2ClientCredentials;
47 import org.onap.so.svnfm.simulator.model.Vnfds;
48 import org.onap.so.svnfm.simulator.repository.VnfOperationRepository;
49 import org.onap.so.svnfm.simulator.config.ApplicationConfig;
50 import org.onap.so.svnfm.simulator.model.VnfOperation;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53 import org.springframework.core.io.ClassPathResource;
54 import org.springframework.core.io.Resource;
55
56 public abstract class OperationProgressor implements Runnable {
57
58     private static final Logger LOGGER = LoggerFactory.getLogger(OperationProgressor.class);
59     private static final String CERTIFICATE_TO_TRUST = "so-vnfm-adapter.crt.pem";
60
61     private Resource keyStoreResource = new ClassPathResource("so-vnfm-simulator.p12");
62     private String keyStorePassword = "7Em3&j4.19xYiMelhD5?xbQ.";
63
64     protected final VnfOperation operation;
65     protected final SvnfmService svnfmService;
66     private final VnfOperationRepository vnfOperationRepository;
67     private final ApplicationConfig applicationConfig;
68     protected final Vnfds vnfds;
69     private final SubscriptionService subscriptionService;
70     private final DefaultApi notificationClient;
71     private final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi grantClient;
72
73     public OperationProgressor(final VnfOperation operation, final SvnfmService svnfmService,
74             final VnfOperationRepository vnfOperationRepository, final ApplicationConfig applicationConfig,
75             final Vnfds vnfds, final SubscriptionService subscriptionService) {
76         this.operation = operation;
77         this.svnfmService = svnfmService;
78         this.vnfOperationRepository = vnfOperationRepository;
79         this.applicationConfig = applicationConfig;
80         this.vnfds = vnfds;
81         this.subscriptionService = subscriptionService;
82
83         final ApiClient apiClient = new ApiClient();
84         String callBackUrl = subscriptionService.getSubscriptions().iterator().next().getCallbackUri();
85         callBackUrl = callBackUrl.substring(0, callBackUrl.indexOf("/lcn/"));
86         apiClient.setBasePath(callBackUrl);
87         apiClient.setKeyManagers(getKeyManagers());
88         apiClient.setSslCaCert(getCertificateToTrust());
89         notificationClient = new DefaultApi(apiClient);
90
91         final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient grantApiClient =
92                 new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiClient();
93         grantApiClient.setBasePath(callBackUrl);
94         grantApiClient.setKeyManagers(getKeyManagers());
95         grantApiClient.setSslCaCert(getCertificateToTrust());
96         grantClient = new org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.api.DefaultApi(grantApiClient);
97     }
98
99     private InputStream getCertificateToTrust() {
100         try {
101             return new ClassPathResource(CERTIFICATE_TO_TRUST).getInputStream();
102         } catch (final IOException exception) {
103             LOGGER.error("Error reading certificate to trust, https calls to VNFM adapter will fail", exception);
104             return null;
105         }
106     }
107
108     private KeyManager[] getKeyManagers() {
109         KeyStore keystore;
110         try {
111             keystore = KeyStore.getInstance("pkcs12");
112             keystore.load(keyStoreResource.getInputStream(), keyStorePassword.toCharArray());
113             KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("SunX509");
114             keyManagerFactory.init(keystore, keyStorePassword.toCharArray());
115             return keyManagerFactory.getKeyManagers();
116         } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException
117                 | UnrecoverableKeyException exception) {
118             LOGGER.error("Error reading certificate, https calls using two way TLS to VNFM adapter will fail",
119                     exception);
120             return new KeyManager[0];
121         }
122     }
123
124     @Override
125     public void run() {
126         try {
127             final VnfLcmOperationOccurrenceNotification notificationOfStarting =
128                     buildNotification(NotificationStatusEnum.START, OperationStateEnum.STARTING);
129             sendNotification(notificationOfStarting);
130
131             sleep(2000);
132             setState(InlineResponse200.OperationStateEnum.PROCESSING);
133             final VnfLcmOperationOccurrenceNotification notificationOfProcessing =
134                     buildNotification(NotificationStatusEnum.START, OperationStateEnum.PROCESSING);
135             sendNotification(notificationOfProcessing);
136
137
138             final GrantRequest grantRequest = buildGrantRequest();
139             final InlineResponse201 grantResponse = sendGrantRequest(grantRequest);
140             final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> vnfcs = handleGrantResponse(grantResponse);
141
142             svnfmService.getVnf(operation.getVnfInstanceId()).getInstantiatedVnfInfo();
143
144             sleep(10000);
145             setState(InlineResponse200.OperationStateEnum.COMPLETED);
146             final VnfLcmOperationOccurrenceNotification notificationOfCompleted =
147                     buildNotification(NotificationStatusEnum.RESULT, OperationStateEnum.COMPLETED);
148             notificationOfCompleted.setAffectedVnfcs(getVnfcs(vnfcs));
149
150             sendNotification(notificationOfCompleted);
151         } catch (final Exception exception) {
152             LOGGER.error("Error in OperationProgressor ", exception);
153         }
154
155     }
156
157     private void sleep(final long milliSeconds) {
158         try {
159             Thread.sleep(milliSeconds);
160         } catch (final InterruptedException e) {
161             operation.setOperationState(InlineResponse200.OperationStateEnum.FAILED);
162             // Restore interrupted state
163             Thread.currentThread().interrupt();
164         }
165     }
166
167     private void setState(final InlineResponse200.OperationStateEnum state) {
168         LOGGER.info("Setting state to {} for operation {}", state, operation.getId());
169         operation.setOperationState(state);
170         vnfOperationRepository.save(operation);
171     }
172
173     private VnfLcmOperationOccurrenceNotification buildNotification(final NotificationStatusEnum status,
174             final OperationStateEnum operationState) {
175         final VnfLcmOperationOccurrenceNotification notification = new VnfLcmOperationOccurrenceNotification();
176         notification.setId(UUID.randomUUID().toString());
177         notification.setNotificationType(NotificationTypeEnum.VNFLCMOPERATIONOCCURRENCENOTIFICATION);
178         notification.setNotificationStatus(status);
179         notification.setOperationState(operationState);
180         notification.setOperation(OperationEnum.fromValue(operation.getOperation().toString()));
181         notification.setVnfInstanceId(operation.getVnfInstanceId());
182         notification.setVnfLcmOpOccId(operation.getId());
183
184         final LcnVnfLcmOperationOccurrenceNotificationLinks links = new LcnVnfLcmOperationOccurrenceNotificationLinks();
185         final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance vnfInstanceLink =
186                 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
187         vnfInstanceLink.setHref(getVnfLink());
188         links.setVnfInstance(vnfInstanceLink);
189
190
191         final LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance operationLink =
192                 new LcnVnfLcmOperationOccurrenceNotificationLinksVnfInstance();
193         operationLink.setHref(getOperationLink());
194         links.setVnfLcmOpOcc(operationLink);
195
196         notification.setLinks(links);
197
198         return notification;
199     }
200
201     private List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> getVnfcs(
202             final List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> instantiatedVnfcs) {
203         final List<LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs> vnfcs = new ArrayList<>();
204         if (instantiatedVnfcs != null) {
205             for (final InlineResponse201InstantiatedVnfInfoVnfcResourceInfo instantiatedVnfc : instantiatedVnfcs) {
206                 LOGGER.info("VNFC TO BE CONVERTED: {}", instantiatedVnfc);
207                 final ModelMapper mapper = new ModelMapper();
208                 final LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs vnfc =
209                         mapper.map(instantiatedVnfc, LcnVnfLcmOperationOccurrenceNotificationAffectedVnfcs.class);
210                 LOGGER.info("VNFC FROM CONVERSION: {}", vnfc);
211                 vnfc.setChangeType(getVnfcChangeType());
212                 vnfcs.add(vnfc);
213             }
214         }
215         return vnfcs;
216     }
217
218     private void sendNotification(final VnfLcmOperationOccurrenceNotification notification) {
219         LOGGER.info("Sending notification: {}", notification);
220         try {
221             final SubscriptionsAuthenticationParamsBasic subscriptionAuthentication =
222                     subscriptionService.getSubscriptions().iterator().next().getAuthentication().getParamsBasic();
223             final String auth =
224                     subscriptionAuthentication.getUserName() + ":" + subscriptionAuthentication.getPassword();
225             final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.ISO_8859_1));
226             String authHeader = "Basic " + new String(encodedAuth);
227
228             notificationClient.lcnVnfLcmOperationOccurrenceNotificationPostWithHttpInfo(notification,
229                     MediaType.APPLICATION_JSON, authHeader);
230         } catch (final ApiException exception) {
231             LOGGER.error("Error sending notification: " + notification, exception);
232             LOGGER.error("Response code: {}, body: {}, basePath: {}", exception.getCode(), exception.getResponseBody(),
233                     notificationClient.getApiClient().getBasePath());
234
235         }
236     }
237
238
239     public GrantRequest buildGrantRequest() {
240         final GrantRequest grantRequest = new GrantRequest();
241         grantRequest.setVnfInstanceId(operation.getVnfInstanceId());
242         final String vnfdId = svnfmService.getVnf(operation.getVnfInstanceId()).getVnfdId();
243         grantRequest.setVnfdId(vnfdId);
244         grantRequest.setAddResources(getAddResources(vnfdId));
245         grantRequest.setRemoveResources(getRemoveResources(vnfdId));
246         grantRequest.setVnfLcmOpOccId(operation.getId());
247         grantRequest
248                 .setOperation(org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.model.GrantRequest.OperationEnum
249                         .fromValue(operation.getOperation().getValue()));
250         grantRequest.setIsAutomaticInvocation(false);
251
252         final GrantsLinksVnfLcmOpOcc vnfInstanceLink = new GrantsLinksVnfLcmOpOcc();
253         vnfInstanceLink.setHref(getVnfLink());
254         final GrantsLinksVnfLcmOpOcc operationInstanceLink = new GrantsLinksVnfLcmOpOcc();
255         operationInstanceLink.setHref(getOperationLink());
256         final GrantsLinks links = new GrantsLinks();
257         links.setVnfInstance(vnfInstanceLink);
258         links.setVnfLcmOpOcc(operationInstanceLink);
259         grantRequest.setLinks(links);
260         return grantRequest;
261     }
262
263     protected abstract List<GrantsAddResources> getAddResources(final String vnfdId);
264
265     protected abstract List<GrantsAddResources> getRemoveResources(final String vnfdId);
266
267     protected abstract List<InlineResponse201InstantiatedVnfInfoVnfcResourceInfo> handleGrantResponse(
268             InlineResponse201 grantResponse);
269
270     protected abstract ChangeTypeEnum getVnfcChangeType();
271
272     private InlineResponse201 sendGrantRequest(final GrantRequest grantRequest) {
273         LOGGER.info("Sending grant request: {}", grantRequest);
274         try {
275
276             final SubscriptionsAuthenticationParamsOauth2ClientCredentials subscriptionAuthentication =
277                     subscriptionService.getSubscriptions().iterator().next().getAuthentication()
278                             .getParamsOauth2ClientCredentials();
279
280             final String authHeader = applicationConfig.getGrantAuth().equals("oauth")
281                     ? "Bearer " + getToken(notificationClient.getApiClient(), subscriptionAuthentication)
282                     : null;
283
284             final ApiResponse<InlineResponse201> response = grantClient.grantsPostWithHttpInfo(grantRequest,
285                     MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON, authHeader);
286             LOGGER.info("Grant Response: {}", response);
287             return response.getData();
288         } catch (final org.onap.so.adapters.vnfmadapter.extclients.vnfm.grant.ApiException exception) {
289             LOGGER.error("Error sending notification: " + grantRequest, exception);
290             return null;
291         }
292     }
293
294     private String getVnfLink() {
295         return getLinkBaseUrl() + "/vnf_instances/" + operation.getVnfInstanceId();
296     }
297
298     private String getOperationLink() {
299         return getLinkBaseUrl() + "/vnf_lcm_op_occs/" + operation.getId();
300     }
301
302     private String getLinkBaseUrl() {
303         return applicationConfig.getBaseUrl() + "/vnflcm/v1";
304     }
305
306     private String getToken(final ApiClient apiClient,
307             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
308         final String basePath = apiClient.getBasePath().substring(0, apiClient.getBasePath().indexOf("/so/"));
309         final String tokenUrl = basePath + "/oauth/token?grant_type=client_credentials";
310
311         try {
312             URL url = new URL(tokenUrl);
313             HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
314             connection.setRequestMethod("POST");
315             final String authorizationHeader = getAuthorizationHeader(oauthClientCredentials);
316             connection.addRequestProperty("Authorization", authorizationHeader);
317
318             connection.connect();
319
320             return getResponse(connection).get("access_token").getAsString();
321
322         } catch (IOException exception) {
323             LOGGER.error("Error getting token", exception);
324             return null;
325         }
326     }
327
328     private String getAuthorizationHeader(
329             final SubscriptionsAuthenticationParamsOauth2ClientCredentials oauthClientCredentials) {
330         final String auth = oauthClientCredentials.getClientId() + ":" + oauthClientCredentials.getClientPassword();
331         final byte[] encodedAuth = Base64.encodeBase64(auth.getBytes(StandardCharsets.UTF_8));
332         return "Basic " + new String(encodedAuth);
333     }
334
335     private JsonObject getResponse(HttpsURLConnection connection) throws IOException {
336         BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
337         String line, data = "";
338         while ((line = in.readLine()) != null) {
339             data += line;
340         }
341         in.close();
342         connection.getInputStream().close();
343
344         JsonObject jsonObject = new JsonParser().parse(data).getAsJsonObject();
345         return jsonObject;
346     }
347
348 }