diff options
author | Matthieu Geerebaert <matthieu.geerebaert@orange.com> | 2019-03-26 15:53:42 +0000 |
---|---|---|
committer | Gerrit Code Review <gerrit@onap.org> | 2019-03-26 15:53:42 +0000 |
commit | db00c26116449ef0a4a882811545fc5c2cb1d34f (patch) | |
tree | 4d46b72c6a8a0b0b774813e6e8c8aad19bc6943f | |
parent | ab3fe2b8e2a08a2e138d269d68d7f48288f9464d (diff) | |
parent | d6f77e245fe28146b1b79a2940ef3ea30cf5a575 (diff) |
Merge "ExtApi Listener Implementation"
-rw-r--r-- | src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java | 90 | ||||
-rwxr-xr-x | src/main/java/org/onap/nbi/apis/hub/HubResource.java | 26 | ||||
-rw-r--r-- | src/main/java/org/onap/nbi/apis/hub/ListenerResource.java | 54 | ||||
-rwxr-xr-x | src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java | 9 | ||||
-rw-r--r-- | src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java | 107 | ||||
-rw-r--r-- | src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java | 35 | ||||
-rw-r--r-- | src/main/resources/application.properties | 3 | ||||
-rw-r--r-- | src/test/java/org/onap/nbi/api/listener/ListenerResourceTest.java (renamed from src/test/java/org/onap/nbi/api/listener/ListenerResource.java) | 4 |
8 files changed, 304 insertions, 24 deletions
diff --git a/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java b/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java new file mode 100644 index 0000000..10d6f7c --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2019 Amdocs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.hub; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.nbi.apis.hub.model.Subscription; +import org.onap.nbi.exceptions.BackendFunctionalException; +import org.onap.nbi.exceptions.TechnicalException; +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.http.*; +import org.springframework.stereotype.Service; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +@Service +public class ExtApiClientForHub { + + @Autowired + RestTemplate restTemplate; + + @Value("${external.nbi.url}") + private String externalNbiUrl; + + @Value("${nbi.url}") + private String nbiUrl; + + private static final Logger LOGGER = LoggerFactory.getLogger(ExtApiClientForHub.class); + + private static final ObjectMapper mapper = new ObjectMapper(); + + public ResponseEntity<Object> postEventSubscription(Subscription subscription, String targetURL) { + try { + + + String url = externalNbiUrl.replace("{targetUrl}", targetURL) + "/hub"; + LOGGER.debug("Sending create event notification request to " + url); + String nbiListenerUrl = nbiUrl + "/listener"; + subscription.setCallback(nbiListenerUrl); + String subscriptionAsBody = mapper.writeValueAsString(subscription); + ResponseEntity<Object> response = postRequest(url, subscriptionAsBody, buildRequestHeaders()); + LOGGER.info("Received response from " + targetURL + "with status : " + response.getStatusCode()); + LOGGER.debug("Response Body: " + response.getBody()); + return response; + }catch(JsonProcessingException ex) { + LOGGER.error("error occurred while parsing service order to Json: " + ex); + throw new TechnicalException("error occurred while parsing service order to Json:"+ HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + private HttpHeaders buildRequestHeaders() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Accept", "application/json"); + httpHeaders.add("Content-Type", "application/json"); + return httpHeaders; + } + + + private ResponseEntity<Object> postRequest(String url, String body, HttpHeaders httpHeaders) { + try { + ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, httpHeaders), Object.class); + return response; + }catch(BackendFunctionalException ex) { + LOGGER.error("error on calling " + url + " ," + ex); + return new ResponseEntity<>("problem calling onap services", ex.getHttpStatus()); + }catch (ResourceAccessException ex) { + LOGGER.error("error on calling " + url + " ," + ex); + return new ResponseEntity<>("unable to reach onap services", HttpStatus.INTERNAL_SERVER_ERROR); + + } + + } +} + diff --git a/src/main/java/org/onap/nbi/apis/hub/HubResource.java b/src/main/java/org/onap/nbi/apis/hub/HubResource.java index 016ebca..a37c522 100755 --- a/src/main/java/org/onap/nbi/apis/hub/HubResource.java +++ b/src/main/java/org/onap/nbi/apis/hub/HubResource.java @@ -43,6 +43,7 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseStatus; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestHeader; @RestController @RequestMapping("/hub") @@ -63,22 +64,27 @@ public class HubResource extends ResourceManagement { @Autowired CheckDMaaPEventsManager checkDMaaPEventMAnager; + @Autowired + ExtApiClientForHub extApiClientForHub; + @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Object> createEventSubscription(@RequestBody Subscription subscription, - @RequestParam MultiValueMap<String, String> params) { + @RequestParam MultiValueMap<String, String> params, @RequestHeader(required = false) String targetURL) { logger.debug("POST request for subscription : {}", subscription); - Subscriber subscriber = subscriptionService.createSubscription(subscription); - JsonRepresentation filter = new JsonRepresentation(params); - return this.createResponse(Subscription.createFromSubscriber(subscriber), filter); - + if(targetURL != null) { + return extApiClientForHub.postEventSubscription(subscription,targetURL); + }else { + Subscriber subscriber = subscriptionService.createSubscription(subscription); + JsonRepresentation filter = new JsonRepresentation(params); + return this.createResponse(Subscription.createFromSubscriber(subscriber), filter); + } } @GetMapping(value = "/{subscriptionId}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Subscription> getSubscription(@PathVariable String subscriptionId) { - Optional<Subscriber> optionalSubscriber = - subscriptionService.findSubscriptionById(subscriptionId); + Optional<Subscriber> optionalSubscriber = subscriptionService.findSubscriptionById(subscriptionId); if (!optionalSubscriber.isPresent()) { return ResponseEntity.notFound().build(); } @@ -86,8 +92,7 @@ public class HubResource extends ResourceManagement { } @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) - public ResponseEntity<Object> findSubscribers( - @RequestParam MultiValueMap<String, String> params) { + public ResponseEntity<Object> findSubscribers(@RequestParam MultiValueMap<String, String> params) { Query query = multiCriteriaRequestBuilder.buildRequest(params); List<Subscriber> subscribers = mongoTemplate.find(query, Subscriber.class); @@ -96,8 +101,7 @@ public class HubResource extends ResourceManagement { HttpHeaders headers = new HttpHeaders(); headers.add("X-Total-Count", String.valueOf(totalCount)); headers.add("X-Result-Count", String.valueOf(subscribers.size())); - List<Subscription> subscriptions = - subscribers.stream().map(Subscription::createFromSubscriber).collect(Collectors.toList()); + List<Subscription> subscriptions = subscribers.stream().map(Subscription::createFromSubscriber).collect(Collectors.toList()); return this.findResponse(subscriptions, filter, headers); diff --git a/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java b/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java new file mode 100644 index 0000000..def2ff0 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2019 Amdocs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.hub; + +import org.onap.nbi.apis.hub.service.NotificationAspect; +import org.onap.nbi.commons.ResourceManagement; +import org.onap.nbi.exceptions.BackendFunctionalException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.scheduling.annotation.EnableScheduling; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import org.onap.nbi.apis.hub.model.Event; + + + +@RestController +@RequestMapping("/listener") +@EnableScheduling +public class ListenerResource extends ResourceManagement { + + @Autowired + NotificationAspect notificationAspect; + + private static final Logger LOGGER = LoggerFactory.getLogger(ListenerResource.class); + + @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) + public void receiveNotification(@RequestBody Event event) { + try { + LOGGER.debug("Received notification from external NBI || Sending it to original listener"); + notificationAspect.forwardNotificationToOriginalListener(event); + }catch(BackendFunctionalException ex) { + LOGGER.error("Unable to send the recieved notification to original Listener"); + + } + } +} diff --git a/src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java b/src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java index cd242e8..3033404 100755 --- a/src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java +++ b/src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java @@ -27,6 +27,7 @@ import org.onap.nbi.apis.serviceorder.model.StateType; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Configurable; import org.springframework.stereotype.Component; +import org.onap.nbi.exceptions.TechnicalException; @Aspect @Component @@ -71,6 +72,14 @@ public class NotificationAspect { } } + public void forwardNotificationToOriginalListener(Event event) { + if(event != null) { + processEvent(event); + }else{ + throw new TechnicalException("Received null event from external NBI"); + } + } + /** * Retreive subscribers that match an event and fire notification * asynchronously diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java b/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java new file mode 100644 index 0000000..7fd06e6 --- /dev/null +++ b/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java @@ -0,0 +1,107 @@ +/** + * Copyright (c) 2019 Amdocs + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onap.nbi.apis.serviceorder; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.onap.nbi.apis.serviceorder.model.ServiceOrder; +import org.onap.nbi.exceptions.BackendFunctionalException; +import org.onap.nbi.exceptions.TechnicalException; +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.http.*; +import org.springframework.stereotype.Service; +import org.springframework.util.MultiValueMap; +import org.springframework.web.client.ResourceAccessException; +import org.springframework.web.client.RestTemplate; + +@Service +public class ExtApiClient { + + @Autowired + RestTemplate restTemplate; + + @Value("${external.nbi.url}") + private String externalNbiUrl; + + private static final Logger LOGGER = LoggerFactory.getLogger(ExtApiClient.class); + + private static final ObjectMapper mapper = new ObjectMapper(); + + public ResponseEntity<Object> postServiceOrder(ServiceOrder serviceOrder, String targetURL) { + try { + + + String url = externalNbiUrl.replace("{targetUrl}", targetURL) + "/serviceOrder"; + LOGGER.debug("Sending create service order request to " + url); + String serviceOrderAsBody = mapper.writeValueAsString(serviceOrder); + ResponseEntity<Object> response = postRequest(url, serviceOrderAsBody, buildRequestHeaders()); + LOGGER.info("Received response from " + targetURL + "with status : " + response.getStatusCode()); + LOGGER.debug("Response Body: " + response.getBody()); + return response; + }catch(JsonProcessingException ex) { + LOGGER.error("error occurred while parsing subscription data to Json: " + ex); + throw new TechnicalException("error occurred while parsing subscription data to Json:"+ HttpStatus.INTERNAL_SERVER_ERROR); + } + } + + private HttpHeaders buildRequestHeaders() { + HttpHeaders httpHeaders = new HttpHeaders(); + httpHeaders.add("Accept", "application/json"); + httpHeaders.add("Content-Type", "application/json"); + return httpHeaders; + } + + public ResponseEntity<Object> getServiceOrder(String serviceOrderId, String targetURL) { + + String url = externalNbiUrl.replace("{targetUrl}", targetURL) + "/serviceOrder/" + serviceOrderId; + LOGGER.debug("Sending get service order request to " + url); + ResponseEntity<Object> response = getRequest(url, buildRequestHeaders()); + LOGGER.info("Received response from " + targetURL + "with status : " + response.getStatusCode()); + LOGGER.debug("Response Body: " + response.getBody()); + return response; + } + + + private ResponseEntity<Object> getRequest(String url, HttpHeaders httpHeaders) { + try { + ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.GET, new HttpEntity<>(httpHeaders), Object.class); + return response; + }catch(BackendFunctionalException ex) { + LOGGER.error("Error occurred while sending post request to " + url); + return new ResponseEntity<>("Found Error: " + ex.getBodyResponse(), ex.getHttpStatus()); + }catch (ResourceAccessException ex) { + LOGGER.error("Error occurred while sending post request to " + url); + return new ResponseEntity<>("Unable to access the resource at " + url, HttpStatus.INTERNAL_SERVER_ERROR); + } +} + + private ResponseEntity<Object> postRequest(String url, String body, HttpHeaders httpHeaders) { + try { + ResponseEntity<Object> response = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, httpHeaders), Object.class); + return response; + }catch(BackendFunctionalException ex) { + LOGGER.error("Error occurred while sending post request to " + url); + return new ResponseEntity<>("Found Error: " + ex.getBodyResponse(), ex.getHttpStatus()); + }catch (ResourceAccessException ex) { + LOGGER.error("Error occurred while sending post request to " + url); + return new ResponseEntity<>("Unable to access the resource at " + url, HttpStatus.INTERNAL_SERVER_ERROR); + } + + } +} diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java b/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java index e34a3e7..f8085b9 100644 --- a/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java +++ b/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java @@ -44,6 +44,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.RequestHeader; @RestController @RequestMapping("/serviceOrder") @@ -70,18 +71,26 @@ public class ServiceOrderResource extends ResourceManagement { @Autowired MultiCriteriaRequestBuilder multiCriteriaRequestBuilder; + @Autowired + ExtApiClient extApiClient; + @GetMapping(value = "/{serviceOrderId}", produces = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Object> getServiceOrder(@PathVariable String serviceOrderId, - @RequestParam MultiValueMap<String, String> params) { + @RequestParam MultiValueMap<String, String> params, @RequestHeader(required = false) String targetURL) { + + if(targetURL != null) { + return extApiClient.getServiceOrder(serviceOrderId, targetURL); + }else { + Optional<ServiceOrder> optionalServiceOrder = serviceOrderService.findServiceOrderById(serviceOrderId); + if (!optionalServiceOrder.isPresent()) { + return ResponseEntity.notFound().build(); + } - Optional<ServiceOrder> optionalServiceOrder = serviceOrderService.findServiceOrderById(serviceOrderId); - if (!optionalServiceOrder.isPresent()) { - return ResponseEntity.notFound().build(); + JsonRepresentation filter = new JsonRepresentation(params); + return this.getResponse(optionalServiceOrder.get(), filter); } - JsonRepresentation filter = new JsonRepresentation(params); - return this.getResponse(optionalServiceOrder.get(), filter); } @GetMapping(value = "", produces = MediaType.APPLICATION_JSON_VALUE) @@ -110,22 +119,26 @@ public class ServiceOrderResource extends ResourceManagement { @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Object> createServiceOrder(@Valid @RequestBody ServiceOrder serviceOrder, Errors errors, - @RequestParam MultiValueMap<String, String> params) { + @RequestParam MultiValueMap<String, String> params, @RequestHeader(required = false) String targetURL) { if (errors != null && errors.hasErrors()) { throw new ValidationException(errors.getAllErrors()); } + if(targetURL != null) { + return extApiClient.postServiceOrder(serviceOrder, targetURL); - ServiceOrder serviceOrderSaved = serviceOrderService.createServiceOrder(serviceOrder); - JsonRepresentation filter = new JsonRepresentation(params); - return this.createResponse(serviceOrderSaved, filter); + }else { + ServiceOrder serviceOrderSaved = serviceOrderService.createServiceOrder(serviceOrder); + JsonRepresentation filter = new JsonRepresentation(params); + return this.createResponse(serviceOrderSaved, filter); + } } @PutMapping(value = "/test/{serviceOrderId}", consumes = MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<Object> checkServiceOrderRessource(@PathVariable String serviceOrderId, - @RequestParam MultiValueMap<String, String> params) { + @RequestParam MultiValueMap<String, String> params) { Optional<ServiceOrder> optionalServiceOrder = serviceOrderService.findServiceOrderById(serviceOrderId); if (!optionalServiceOrder.isPresent()) { return ResponseEntity.notFound().build(); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index fe7dde0..d488505 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -42,6 +42,9 @@ onap.cloudOwner = CloudOwner nbi.url = http://localhost:${server.port}${server.servlet.context-path} nbi.callForVNF = false +# External NBI +external.nbi.url = http://{targetUrl}:${server.port}${server.servlet.context-path} + # SCHEDULER scheduler.pollingDurationInMins = 360 serviceOrder.schedule = 5000 diff --git a/src/test/java/org/onap/nbi/api/listener/ListenerResource.java b/src/test/java/org/onap/nbi/api/listener/ListenerResourceTest.java index 8fb276d..691592a 100644 --- a/src/test/java/org/onap/nbi/api/listener/ListenerResource.java +++ b/src/test/java/org/onap/nbi/api/listener/ListenerResourceTest.java @@ -38,9 +38,9 @@ import com.fasterxml.jackson.databind.JsonNode; @RestController @RequestMapping("/test/listener") -public class ListenerResource extends ResourceManagement { +public class ListenerResourceTest extends ResourceManagement { - Logger logger = LoggerFactory.getLogger(ListenerResource.class); + Logger logger = LoggerFactory.getLogger(ListenerResourceTest.class); static Map<String, JsonNode> events = new ConcurrentHashMap<>(); |