2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2020 Nordix Foundation.
4 * ================================================================================
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.so.svnfm.simulator.controller;
23 import javax.ws.rs.core.MediaType;
24 import com.google.gson.Gson;
25 import com.google.gson.GsonBuilder;
26 import com.google.gson.JsonObject;
27 import com.google.gson.JsonParser;
28 import com.google.gson.TypeAdapter;
29 import com.google.gson.stream.JsonReader;
30 import com.google.gson.stream.JsonWriter;
31 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.InlineResponse201;
32 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.PkgmSubscriptionRequest;
33 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication;
34 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthentication.AuthTypeEnum;
35 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.model.SubscriptionsAuthenticationParamsBasic;
36 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageChangeNotification;
37 import org.onap.so.adapters.vnfmadapter.extclients.vnfm.packagemanagement.notification.model.VnfPackageOnboardingNotification;
38 import org.onap.so.svnfm.simulator.constants.Constant;
39 import org.onap.so.svnfm.simulator.services.SubscriptionManager;
40 import org.onap.so.svnfm.simulator.services.providers.VnfPkgOnboardingNotificationCacheServiceProviderImpl;
41 import org.slf4j.Logger;
42 import org.slf4j.LoggerFactory;
43 import org.springframework.beans.factory.annotation.Autowired;
44 import org.springframework.beans.factory.annotation.Value;
45 import org.springframework.http.HttpStatus;
46 import org.springframework.http.ResponseEntity;
47 import org.springframework.web.bind.annotation.GetMapping;
48 import org.springframework.web.bind.annotation.PathVariable;
49 import org.springframework.web.bind.annotation.PostMapping;
50 import org.springframework.web.bind.annotation.RequestBody;
51 import org.springframework.web.bind.annotation.RequestMapping;
52 import org.springframework.web.bind.annotation.RestController;
53 import java.io.IOException;
54 import java.time.LocalDateTime;
55 import java.time.format.DateTimeFormatter;
56 import java.util.Optional;
59 * @author Eoin Hanan (eoin.hanan@est.tech)
60 * @author Andrew Lamb (andrew.a.lamb@est.tech)
64 @RequestMapping(path = Constant.PACKAGE_MANAGEMENT_BASE_URL, produces = MediaType.APPLICATION_JSON, consumes = MediaType.APPLICATION_JSON)
65 public class SubscriptionNotificationController {
67 private static final Logger logger = LoggerFactory.getLogger(SubscriptionNotificationController.class);
68 private final Gson gson;
70 private SubscriptionManager subscriptionManager;
72 private VnfPkgOnboardingNotificationCacheServiceProviderImpl vnfPkgOnboardingNotificationCacheServiceProvider;
75 public SubscriptionNotificationController() {
76 this.gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new LocalDateTimeTypeAdapter()).create();
79 @Value("${spring.security.usercredentials[0].username}")
80 private String username;
81 @Value("${spring.security.usercredentials[0].password}")
82 private String password;
84 @GetMapping(produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
85 public ResponseEntity<Void> testEndpoint() {
86 logger.info("Testing SubscriptionNotification Endpoint");
87 return ResponseEntity.noContent().build();
91 * Send subscription request
93 * @param pkgmSubscriptionRequest The subscription request
96 @PostMapping(value = Constant.SUBSCRIPTION_ENDPOINT, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
97 public ResponseEntity<?> subscribeForNotifications(@RequestBody final PkgmSubscriptionRequest pkgmSubscriptionRequest){
98 logger.info("Vnf Package Subscription Request received:\n{}", pkgmSubscriptionRequest);
100 if(pkgmSubscriptionRequest.getCallbackUri()==null){
101 logger.info("Subscription Request does not include call back URI ");
102 pkgmSubscriptionRequest.setCallbackUri(Constant.PACKAGE_MANAGEMENT_BASE_URL + Constant.NOTIFICATION_ENDPOINT);
105 if(pkgmSubscriptionRequest.getAuthentication()==null) {
106 pkgmSubscriptionRequest.setAuthentication(new SubscriptionsAuthentication()
107 .addAuthTypeItem(AuthTypeEnum.BASIC)
108 .paramsBasic(new SubscriptionsAuthenticationParamsBasic().userName(username).password(password)));
111 logger.info("Final Request being sent:\n{}", pkgmSubscriptionRequest);
113 final InlineResponse201 response = subscriptionManager.createSubscription(pkgmSubscriptionRequest);
114 logger.info("Response is:\n{}", response);
116 return ResponseEntity.ok().body(response);
120 * Endpoint to receive VNF package notifications
122 * @param notification The notification received
125 @PostMapping(value = Constant.NOTIFICATION_ENDPOINT, produces = {MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
126 public ResponseEntity<?> postVnfPackageNotification(@RequestBody final Object notification){
127 logger.info("Vnf Notification received:\n{}", notification);
128 final String notificationString = gson.toJson(notification);
129 addNotificationObjectToCache(notificationString);
130 return ResponseEntity.noContent().build();
134 * Testing endpoint for checking that notifications have been received
139 @GetMapping(value = Constant.NOTIFICATION_CACHE_TEST_ENDPOINT)
140 public ResponseEntity<?> getVnfPackageNotification(@PathVariable("vnfPkgId") final String vnfPkgId) {
141 logger.info("Getting notification with vnfPkgId: {}", vnfPkgId);
142 final Optional<VnfPackageOnboardingNotification> optionalVnfPackageOnboardingNotification =
143 vnfPkgOnboardingNotificationCacheServiceProvider.getVnfPkgOnboardingNotification(vnfPkgId);
144 if(optionalVnfPackageOnboardingNotification.isPresent()) {
145 VnfPackageOnboardingNotification vnfPackageOnboardingNotification =
146 optionalVnfPackageOnboardingNotification.get();
147 logger.info("Return notification with vnfPkgId: {} and body {}", vnfPkgId, vnfPackageOnboardingNotification);
148 return ResponseEntity.ok().body(vnfPackageOnboardingNotification);
150 final String errorMessage = "No notification found with vnfPkgId: " + vnfPkgId;
151 logger.error(errorMessage);
152 return ResponseEntity.status(HttpStatus.NOT_FOUND).body(errorMessage);
155 private void addNotificationObjectToCache(final String notification) {
156 logger.info("addNotificationObjectToCache(): {}", notification);
157 final String notificationType = getNotificationType(notification);
158 if (VnfPackageOnboardingNotification.NotificationTypeEnum.VNFPACKAGEONBOARDINGNOTIFICATION.getValue()
159 .equals(notificationType)) {
160 final VnfPackageOnboardingNotification pkgOnboardingNotification =
161 gson.fromJson(notification, VnfPackageOnboardingNotification.class);
162 logger.info("Onboarding notification received:\n{}", pkgOnboardingNotification);
163 final String vnfPkgId = pkgOnboardingNotification.getVnfPkgId();
164 vnfPkgOnboardingNotificationCacheServiceProvider.addVnfPkgOnboardingNotification(vnfPkgId, pkgOnboardingNotification);
165 } else if (VnfPackageChangeNotification.NotificationTypeEnum.VNFPACKAGECHANGENOTIFICATION.getValue()
166 .equals(notificationType)) {
167 final VnfPackageChangeNotification pkgChangeNotification =
168 gson.fromJson(notification, VnfPackageChangeNotification.class);
169 logger.info("Change notification received:\n{}", pkgChangeNotification);
171 final String errorMessage = "An error occurred. Notification type not supported for: " + notificationType;
172 logger.error(errorMessage);
173 throw new RuntimeException(errorMessage);
177 private String getNotificationType(final String notification) {
179 logger.info("getNotificationType() notification: {}", notification);
180 final JsonParser parser = new JsonParser();
181 final JsonObject element = (JsonObject) parser.parse(notification);
182 return element.get("notificationType").getAsString();
183 } catch (final Exception e) {
184 logger.error("An error occurred processing notificiation: {}", e.getMessage());
186 throw new RuntimeException(
187 "Unable to parse notification type in object \n" + notification);
190 public static class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {
192 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
195 public void write(final JsonWriter out, final LocalDateTime localDateTime) throws IOException {
196 if (localDateTime == null) {
199 out.value(FORMATTER.format(localDateTime));
204 public LocalDateTime read(final JsonReader in) throws IOException {
210 final String dateTime = in.nextString();
211 return LocalDateTime.parse(dateTime, FORMATTER);