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