CCVPN (East-west Interface) 90/83190/3
authorVodafone <onap@vodafone.com>
Mon, 25 Mar 2019 12:08:23 +0000 (17:38 +0530)
committerMatthieu Geerebaert <matthieu.geerebaert@orange.com>
Fri, 12 Apr 2019 12:13:40 +0000 (14:13 +0200)
Change-Id: I11dbe477db3310ef054b2e894e8005b0f8e4be96
Issue-ID: EXTAPI-204
Co-authored-by: madhuri.verma@vodafone.com
Signed-off-by: Vodafone <onap@vodafone.com>
20 files changed:
docs/configuration/configuration.rst
src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java [deleted file]
src/main/java/org/onap/nbi/apis/hub/HubResource.java
src/main/java/org/onap/nbi/apis/hub/ListenerResource.java [deleted file]
src/main/java/org/onap/nbi/apis/hub/model/Subscriber.java
src/main/java/org/onap/nbi/apis/hub/model/Subscription.java
src/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java
src/main/java/org/onap/nbi/apis/listener/ListenerResourceTarget.java [new file with mode: 0644]
src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java
src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java [deleted file]
src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java
src/main/java/org/onap/nbi/commons/EWInterfaceUtils.java [new file with mode: 0644]
src/main/resources/application.properties
src/test/resources/karatetest/data/Event.json [deleted file]
src/test/resources/karatetest/data/subscriber.json
src/test/resources/karatetest/features/02--ServiceOrder.feature
src/test/resources/karatetest/features/03--Subscriber.feature
src/test/resources/karatetest/features/05--ListenerResourceTestTarget.feature [new file with mode: 0644]

index 6290691..a498e4d 100644 (file)
@@ -25,6 +25,7 @@ Default values
     # SERVER
     server.servlet.context-path          = /nbi/api/${nbi.version}
     server.port                          = 8080
+    server.public.ip                     = localhost
 
     # LOGGING
     logging.level.                       = WARN
@@ -41,6 +42,7 @@ Default values
     # NBI
     nbi.url                              = http://localhost:${server.port}${server.servlet.context-path}
     nbi.callForVNF                       = false
+    nbi.public.url                       = http://${server.public.ip}:${server.port}${server.servlet.context-path}
 
     # SCHEDULER
     scheduler.pollingDurationInMins      = 360
index 0796c2f..8828321 100644 (file)
@@ -23,6 +23,15 @@ public final class OnapComponentsUrlPaths {
 
     private OnapComponentsUrlPaths() {}
 
+    // NBI
+    public static final String SERVICE_ORDER_PATH= "/serviceOrder";
+    public static final String SERVICE_INVENTORY_PATH= "/service";
+    public static final String SERVICE_SPECIFICATION_PATH= "/serviceSpecification";
+    public static final String HUB_PATH= "/hub";
+    public static final String LISTENER_PATH= "/listener";
+
+
+
     // SDC
     public static final String SDC_ROOT_URL = "/sdc/v1/catalog/services";
     public static final String SDC_GET_PATH = "/metadata";
@@ -60,4 +69,5 @@ public final class OnapComponentsUrlPaths {
     // DMaaP Message Router REST Client
     public static final String DMAAP_CONSUME_EVENTS =
             "/events/$topic/$consumergroup/$consumerid?timeout=$timeout";
+
 }
\ No newline at end of file
diff --git a/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java b/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java
deleted file mode 100644 (file)
index 10d6f7c..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- *     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);
-
-        }
-
-    }
-}
-
index 28e1313..3f14b8a 100755 (executable)
  */
 package org.onap.nbi.apis.hub;
 
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Optional;
 import java.util.stream.Collectors;
+import org.onap.nbi.OnapComponentsUrlPaths;
 import org.onap.nbi.apis.hub.model.Subscriber;
 import org.onap.nbi.apis.hub.model.Subscription;
 import org.onap.nbi.apis.hub.service.dmaap.CheckDMaaPEventsManager;
 import org.onap.nbi.apis.hub.service.SubscriptionService;
+import org.onap.nbi.commons.EWInterfaceUtils;
 import org.onap.nbi.commons.JsonRepresentation;
 import org.onap.nbi.commons.MultiCriteriaRequestBuilder;
 import org.onap.nbi.commons.ResourceManagement;
 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.data.mongodb.core.MongoTemplate;
 import org.springframework.data.mongodb.core.query.Query;
 import org.springframework.http.HttpHeaders;
@@ -39,14 +43,14 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
 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")
+@RequestMapping(OnapComponentsUrlPaths.HUB_PATH)
 @EnableScheduling
 public class HubResource extends ResourceManagement {
 
@@ -65,27 +69,40 @@ public class HubResource extends ResourceManagement {
   CheckDMaaPEventsManager checkDMaaPEventMAnager;
 
   @Autowired
-  ExtApiClientForHub extApiClientForHub;
+  EWInterfaceUtils ewInterfaceUtils;
+
+  @Value("${nbi.public.url}")
+  private String nbiPublicUrl;
 
   @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
   public ResponseEntity<Object> createEventSubscription(@RequestBody Subscription subscription,
-                                                        @RequestParam MultiValueMap<String, String> params, @RequestHeader(required = false) String targetURL) {
+      @RequestParam MultiValueMap<String, String> params, @RequestHeader(value="Target",required = false)String targetUrl) {
     logger.debug("POST request for subscription : {}", subscription);
-    if(targetURL != null) {
-      Subscriber subscriber = subscriptionService.createSubscription(subscription);
-      return extApiClientForHub.postEventSubscription(subscription,targetURL);
-    }else {
-      Subscriber subscriber = subscriptionService.createSubscription(subscription);
-      JsonRepresentation filter = new JsonRepresentation(params);
-      return this.createResponse(Subscription.createFromSubscriber(subscriber), filter);
+    if (targetUrl != null) {
+      targetUrl = targetUrl + OnapComponentsUrlPaths.HUB_PATH;
+      String originalCallback = subscription.getCallback();
+      subscription.setCallback(nbiPublicUrl + OnapComponentsUrlPaths.LISTENER_PATH);
+      ResponseEntity ewResponse = ewInterfaceUtils.callPostRequestTarget(subscription, targetUrl);
+      if (ewResponse.getStatusCode() == HttpStatus.CREATED) {
+        subscription.setCallback(originalCallback);
+       subscription.setEwHost(targetUrl);
+       subscription.setEwId(((LinkedHashMap)ewResponse.getBody()).get( "id" ).toString());
+      } else {
+        return ewResponse;
+      }
     }
+    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();
     }
@@ -93,7 +110,8 @@ 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);
@@ -102,7 +120,8 @@ 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);
 
@@ -121,7 +140,19 @@ public class HubResource extends ResourceManagement {
   @ResponseStatus(HttpStatus.NO_CONTENT)
   public void deleteSubscription(@PathVariable String subscriptionId) {
     logger.debug("DELETE request for subscription id #{}", subscriptionId);
+    Optional<Subscriber> optionalSubscriber= subscriptionService.findSubscriptionById(subscriptionId);
     subscriptionService.deleteSubscription(subscriptionId);
+    String ewHost=optionalSubscriber.get().getEwHost();
+    String ewId=optionalSubscriber.get().getEwId();
+    logger.info("POST delete for ewHost : {}", ewHost);
+    logger.info("POST delete for ewId : {}", ewId);
+    if ( ewHost !=null && ewId !=null )
+    {
+      logger.info("POST deleteIF for ewHost : {}", ewHost);
+      String targetUrl = ewHost+ "/" + ewId;
+      ewInterfaceUtils.callDeleteRequestTarget(targetUrl);
+      logger.info("POST deleteIF for ewHost is : {}", targetUrl);
+    }
   }
 
 }
diff --git a/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java b/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java
deleted file mode 100644 (file)
index aa236d1..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/**
- *     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")
-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");
-
-        }
-    }
-}
index ab2b05f..582b14b 100755 (executable)
@@ -34,6 +34,26 @@ public class Subscriber implements Resource {
     private String id;
     private String callback;
 
+    public String getEwId() {
+        return ewId;
+    }
+
+    public void setEwId(String ewId) {
+        this.ewId = ewId;
+    }
+
+    private String ewId;
+
+    public String getEwHost() {
+        return ewHost;
+    }
+
+    public void setEwHost(String ewHost) {
+        this.ewHost = ewHost;
+    }
+
+    private String ewHost;
+
     private Map<String, String[]> query = new HashMap<>();
 
     public String getId() {
@@ -59,6 +79,8 @@ public class Subscriber implements Resource {
     public static Subscriber createFromSubscription(Subscription request) {
         Subscriber sub = new Subscriber();
         sub.setCallback(request.getCallback());
+        sub.setEwId( request.getEwId());
+        sub.setEwHost( request.getEwHost());
 
         Stream.of(request.getQuery().split("&"))
                 .map(q -> q.split("="))
index 34e23e1..646d39b 100755 (executable)
@@ -26,6 +26,26 @@ public class Subscription implements Resource{
     private String callback;
 
     private String query;
+    private String ewId;
+    private String ewHost;
+
+    public void setEwHost(String ewHost) {
+        this.ewHost = ewHost;
+    }
+
+    public String getEwId() {
+        return ewId;
+    }
+
+    public void setEwId(String ewId) {
+        this.ewId = ewId;
+    }
+
+
+
+    public String getEwHost() {
+        return ewHost;
+    }
 
     public Subscription(){
 
@@ -65,6 +85,9 @@ public class Subscription implements Resource{
         Subscription sub = new Subscription();
         sub.setId(subscriber.getId());
         sub.setCallback(subscriber.getCallback());
+        sub.setEwId( subscriber.getEwId());
+        sub.setEwHost( subscriber.getEwHost());
+
 
         String query = subscriber.getQuery().entrySet()
                 .stream()
index 3033404..cd242e8 100755 (executable)
@@ -27,7 +27,6 @@ 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
@@ -72,14 +71,6 @@ 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/listener/ListenerResourceTarget.java b/src/main/java/org/onap/nbi/apis/listener/ListenerResourceTarget.java
new file mode 100644 (file)
index 0000000..8b8e50f
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * 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.listener;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.MappingJsonFactory;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.onap.nbi.apis.hub.repository.SubscriberRepository;
+import org.onap.nbi.apis.hub.service.NotifierService;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.onap.nbi.apis.hub.model.Event;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class ListenerResourceTarget {
+    private static final ObjectMapper mapper = new ObjectMapper(new MappingJsonFactory());
+
+    @Autowired
+    private SubscriberRepository subscriberRepository;
+    @Autowired
+    private NotifierService notifier;
+
+    Logger logger = LoggerFactory.getLogger(ListenerResourceTarget.class);
+
+    static Map<String, JsonNode> events = new ConcurrentHashMap<>();
+
+    /*
+        listener resource test for hub resource
+     */
+    @PostMapping(consumes = MediaType.APPLICATION_JSON_VALUE)
+    public ResponseEntity<Object> postListenerResource(@RequestBody JsonNode event) {
+        if (logger.isDebugEnabled()) {
+            logger.debug("POST event from nbi : {}", event.toString());
+
+        }
+        try {
+            Event eventListener = mapper.treeToValue(event, Event.class);
+            subscriberRepository
+                    .findSubscribersUsingEvent(eventListener)
+                    .forEach(sub -> notifier.run(sub, eventListener));
+        }
+        catch(Exception e){
+            logger.error("listener not called " + " ," + e.getMessage());
+            return ResponseEntity.badRequest().build();
+        }
+
+        return ResponseEntity.ok().build();
+    }
+}
+
index 6484672..49b9f08 100644 (file)
@@ -18,6 +18,7 @@ package org.onap.nbi.apis.servicecatalog;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import org.onap.nbi.OnapComponentsUrlPaths;
 import org.onap.nbi.commons.JsonRepresentation;
 import org.onap.nbi.commons.ResourceManagement;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +32,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
-@RequestMapping("/serviceSpecification")
+@RequestMapping(OnapComponentsUrlPaths.SERVICE_SPECIFICATION_PATH)
 public class ServiceSpecificationResource extends ResourceManagement {
 
 
index cd46d74..eda6f96 100644 (file)
@@ -18,6 +18,7 @@ package org.onap.nbi.apis.serviceinventory;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import org.onap.nbi.OnapComponentsUrlPaths;
 import org.onap.nbi.commons.JsonRepresentation;
 import org.onap.nbi.commons.ResourceManagement;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -31,7 +32,7 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 @RestController
-@RequestMapping("/service")
+@RequestMapping(OnapComponentsUrlPaths.SERVICE_INVENTORY_PATH)
 public class ServiceInventoryResource extends ResourceManagement {
 
     @Autowired
diff --git a/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java b/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java
deleted file mode 100644 (file)
index 7fd06e6..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- *     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);
-        }
-
-    }
-}
index f8085b9..90d84a4 100644 (file)
@@ -15,6 +15,8 @@ package org.onap.nbi.apis.serviceorder;
 import java.util.List;
 import java.util.Optional;
 import javax.validation.Valid;
+import org.onap.nbi.OnapComponentsUrlPaths;
+import org.onap.nbi.commons.EWInterfaceUtils;
 import org.onap.nbi.apis.serviceorder.model.ServiceOrder;
 import org.onap.nbi.apis.serviceorder.model.StateType;
 import org.onap.nbi.apis.serviceorder.model.orchestrator.ServiceOrderInfo;
@@ -41,13 +43,13 @@ import org.springframework.web.bind.annotation.PathVariable;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.PutMapping;
 import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestHeader;
 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")
+@RequestMapping(OnapComponentsUrlPaths.SERVICE_ORDER_PATH)
 public class ServiceOrderResource extends ResourceManagement {
 
     @Autowired
@@ -72,25 +74,24 @@ public class ServiceOrderResource extends ResourceManagement {
     MultiCriteriaRequestBuilder multiCriteriaRequestBuilder;
 
     @Autowired
-    ExtApiClient extApiClient;
+    EWInterfaceUtils eWInterfaceUtils;
 
 
     @GetMapping(value = "/{serviceOrderId}", produces = MediaType.APPLICATION_JSON_VALUE)
     public ResponseEntity<Object> getServiceOrder(@PathVariable String serviceOrderId,
-                                                  @RequestParam MultiValueMap<String, String> params, @RequestHeader(required = false) String targetURL) {
-
-        if(targetURL != null) {
-            return extApiClient.getServiceOrder(serviceOrderId, targetURL);
-        }else {
+        @RequestParam MultiValueMap<String, String> params,@RequestHeader(value="Target",required = false)String targetUrl) {
+        if (targetUrl != null) {
+            targetUrl = targetUrl + OnapComponentsUrlPaths.SERVICE_ORDER_PATH + "/" + serviceOrderId;
+            return eWInterfaceUtils.callGetRequestTarget(targetUrl);
+        } else {
             Optional<ServiceOrder> optionalServiceOrder = serviceOrderService.findServiceOrderById(serviceOrderId);
             if (!optionalServiceOrder.isPresent()) {
                 return ResponseEntity.notFound().build();
+            } else {
+                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)
@@ -119,26 +120,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, @RequestHeader(required = false) String targetURL) {
-
-        if (errors != null && errors.hasErrors()) {
-            throw new ValidationException(errors.getAllErrors());
+        @RequestParam MultiValueMap<String, String> params, @RequestHeader(value="Target",required = false)String targetUrl) {
+        if (targetUrl != null) {
+            targetUrl = targetUrl + OnapComponentsUrlPaths.SERVICE_ORDER_PATH;
+            return eWInterfaceUtils.callPostRequestTarget(serviceOrder, targetUrl);
+        } else {
+            if (errors != null && errors.hasErrors()) {
+                throw new ValidationException(errors.getAllErrors());
+            }
         }
-        if(targetURL != null) {
-            return extApiClient.postServiceOrder(serviceOrder, targetURL);
 
-        }else {
-            ServiceOrder serviceOrderSaved = serviceOrderService.createServiceOrder(serviceOrder);
-            JsonRepresentation filter = new JsonRepresentation(params);
-            return this.createResponse(serviceOrderSaved, filter);
-        }
+        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/java/org/onap/nbi/commons/EWInterfaceUtils.java b/src/main/java/org/onap/nbi/commons/EWInterfaceUtils.java
new file mode 100644 (file)
index 0000000..24bf1fc
--- /dev/null
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2019 Vodafone Group
+ *
+ * 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.commons;
+import org.onap.nbi.exceptions.BackendFunctionalException;
+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 EWInterfaceUtils {
+
+    public static final String RESPONSE_STATUS = "response status : ";
+    public static final String RETURNS = " returns ";
+    public static final String ERROR_ON_CALLING = "error on calling ";
+    private static final Logger LOGGER = LoggerFactory.getLogger( EWInterfaceUtils.class);
+    @Autowired
+    private RestTemplate restTemplate;
+    @Value("${so.host}")
+    private String soHostname;
+
+    @Value("${so.api.id}")
+    private String soApiId;
+
+    @Value("${so.header.authorization}")
+    private String soHeaderAuthorization;
+
+    private static final String HEADER_AUTHORIZATION = "Authorization";
+    private static final String X_FROM_APP_ID = "X-FromAppId";
+
+
+    public ResponseEntity<Object> callPostRequestTarget(Object obj, String targetUrl) {
+
+        try {
+            ResponseEntity<Object> response = restTemplate.exchange(targetUrl, HttpMethod.POST,
+                    new HttpEntity<>(obj, buildRequestHeader()), Object.class);
+
+            logResponseGet(targetUrl, response);
+            if (null == response) {
+                return null;
+            } else {
+                return response;
+            }
+
+        } catch (BackendFunctionalException | ResourceAccessException e) {
+            LOGGER.error(ERROR_ON_CALLING  + " ," + e.getMessage());
+            return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
+        }
+    }
+
+
+    public ResponseEntity<Object> callGetRequestTarget(String targetUrl) {
+        try {
+            ResponseEntity<Object> response = restTemplate.exchange(targetUrl, HttpMethod.GET,
+                    new HttpEntity<>(buildRequestHeader()), Object.class);
+            LOGGER.info("response status : {}", targetUrl);
+            logResponseGet(targetUrl, response);
+            if (null == response) {
+                return null;
+            } else {
+                return response;
+            }
+
+        } catch (BackendFunctionalException | ResourceAccessException e) {
+            LOGGER.error(ERROR_ON_CALLING + targetUrl + " ," + e);
+            return null;
+        }
+    }
+
+    public ResponseEntity<Object> callDeleteRequestTarget(String targetUrl) {
+        try {
+            ResponseEntity<Object> response = restTemplate.exchange(targetUrl, HttpMethod.DELETE,
+                    new HttpEntity<>(buildRequestHeader()), Object.class);
+            LOGGER.info("response status ewhost : {}", targetUrl);
+
+            if (null == response) {
+                return null;
+            } else {
+                return response;
+            }
+
+        } catch (BackendFunctionalException | ResourceAccessException e) {
+            LOGGER.error(ERROR_ON_CALLING + targetUrl + " ," + e);
+            return null;
+        }
+    }
+    private void logResponseGet(String url, ResponseEntity<Object> response) {
+        if (response != null) {
+            if (LOGGER.isDebugEnabled()) {
+                LOGGER.debug("response body : {}", response.getBody().toString());
+            }
+            if (LOGGER.isWarnEnabled() && !response.getStatusCode().equals( HttpStatus.OK)) {
+                LOGGER.warn("HTTP call EWInterface on {} returns {} , {}", url, response.getStatusCodeValue(),
+                        response.getBody().toString());
+            }
+        } else {
+            LOGGER.info("no response calling url {}", url);
+        }
+    }
+
+    private HttpHeaders buildRequestHeader() {
+        HttpHeaders httpHeaders = new HttpHeaders();
+        httpHeaders.add(HEADER_AUTHORIZATION, soHeaderAuthorization);
+        httpHeaders.add(X_FROM_APP_ID, soApiId);
+        httpHeaders.add("Accept", "application/json");
+        httpHeaders.add("Content-Type", "application/json");
+        return httpHeaders;
+    }
+}
index 5b908b3..f290102 100644 (file)
@@ -25,6 +25,7 @@ nbi.version                          = v4
 # SERVER
 server.servlet.context-path          = /nbi/api/${nbi.version}
 server.port                          = 8080
+server.public.ip                     = localhost
 
 # LOGGING
 logging.level.                       = WARN
@@ -40,11 +41,9 @@ onap.cloudOwner                      = CloudOwner
 
 # NBI
 nbi.url                              = http://localhost:${server.port}${server.servlet.context-path}
+nbi.public.url                       = http://${server.public.ip}:${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/resources/karatetest/data/Event.json b/src/test/resources/karatetest/data/Event.json
deleted file mode 100644 (file)
index 5887deb..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-[{
-    "eventType": "ServiceOrderStateChangeNotification",
-    "eventDate": "2019-03-27T14:58:32.740Z",
-    "eventId": "12345",
-    "event": {
-      "id": "testEventId",
-      "href": "www.testHref.com",
-      "externalId": "testExternalId",
-      "state": "acknowledged",
-      "orderDate": "2019-03-27T04:58:32.740Z"
-
-  }
-}]
\ No newline at end of file
index 14dfdb8..5fceb9f 100644 (file)
@@ -11,9 +11,5 @@
   {
     "callback": "http://localhost/test",
     "query": "eventType=ServiceOrderItemStateChangeNotification"
-  },
-  {
-    "callback": "http://localhost:8080/nbi/api/v4/test/listener",
-    "query": "eventType=ServiceOrderStateChangeNotification"
   }
 ]
\ No newline at end of file
index 756a00e..4b4891d 100644 (file)
@@ -359,6 +359,19 @@ Given path 'serviceOrder',serviceOrderId16
 When method delete
 Then status 204
 
+Scenario: testCheckServiceOrderWithTargetHeader
+Given path 'serviceOrder'
+And header Target = 'http://localhost:8080/nbi/api/v4'
+And request data[0]
+When method post
+Then status 201
+And match $.id contains '#notnull'
+And match $.state == 'acknowledged'
+And def serviceOrderId = $.id
+Given path 'serviceOrder',serviceOrderId
+And header Target = 'http://localhost:8080/nbi/api/v4'
+When method get
+Then status 200
 
 Scenario: testCheckServiceOrderWithCustomerAAINotResponding
 * call Context.removeWireMockMapping("/aai/v14/business/customers/customer/new");
@@ -436,17 +449,3 @@ Given path 'serviceOrder',serviceOrderId
 When method get
 Then status 200
 * call Context.startServers();
-
-Scenario: testCheckServiceOrderWithTargetURLPresent
-Given path 'serviceOrder'
-And header targetURL = '127.0.0.1'
-And request data[0]
-When method post
-Then status 201
-And match $.id contains '#notnull'
-And match $.state == 'acknowledged'
-And def serviceOrderId = $.id
-Given path 'serviceOrder', serviceOrderId
-And header targetURL = '127.0.0.1'
-When method get
-Then status 200
\ No newline at end of file
index ea8c24a..1d9bfdf 100644 (file)
@@ -9,7 +9,6 @@ Background:
 * call Context.startServers();
 * def data = read('../data/subscriber.json')
 * def serviceOrderData = read('../data/serviceOrder.json')
-* def eventData = read('../data/Event.json')
 * configure retry = { count: 10, interval: 500 }
 * def checkDateFormat =
 """
@@ -250,38 +249,3 @@ Then status 204
 Given path 'test/listener',eventId
 When method delete
 Then status 204
-
-
-Scenario: testHubAndListenerResourceWhenTargetURLIsPresent
-Given path 'hub'
-And header targetURL = '127.0.0.1'
-And request data[3]
-When method post
-Then status 201
-And def location = responseHeaders['Location'][0]
-Given path "listener"
-And request eventData[0]
-When method post
-Then status 200
-Given path "test/listener/12345"
-When method get
-Then status 200
-And match $ contains
-"""
-{
-    "eventType": "ServiceOrderStateChangeNotification",
-    "eventDate": "2019-03-27T14:58:32.740Z",
-    "eventId": "12345",
-    "event": {
-      "id": "testEventId",
-      "href": "www.testHref.com",
-      "externalId": "testExternalId",
-      "state": "acknowledged",
-      "orderDate": "2019-03-27T04:58:32.740Z"
-
-    }
-}
-"""
-Given url location
-When method delete
-Then status 204
diff --git a/src/test/resources/karatetest/features/05--ListenerResourceTestTarget.feature b/src/test/resources/karatetest/features/05--ListenerResourceTestTarget.feature
new file mode 100644 (file)
index 0000000..a42f9b7
--- /dev/null
@@ -0,0 +1,74 @@
+# new feature
+# Tags: optional
+
+Feature: Listener
+
+Background:
+* url nbiBaseUrl
+* def Context = Java.type('org.onap.nbi.test.Context');
+* call Context.startServers();
+* def data = read('../data/subscriber.json')
+* def serviceOrderData = read('../data/serviceOrder.json')
+* configure retry = { count: 10, interval: 500 }
+* def checkDateFormat =
+"""
+function(s) {
+  var SimpleDateFormat = Java.type("java.text.SimpleDateFormat");
+  var sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
+  return sdf.parse(s);
+}
+"""
+
+Scenario: testcreateEventSubscription
+Given path 'hub'
+And header Target = 'http://localhost:8080/nbi/api/v4'
+And request data[0]
+When method post
+Then status 201
+And def hubId = $.id
+And header Target = 'http://localhost:8080/nbi/api/v4'
+Given path 'hub',hubId
+When method get
+Then status 200
+And match hubId == $.id
+Given path 'hub',hubId
+And header Target = 'http://localhost:8080/nbi/api/v4'
+When method delete
+Then status 204
+
+Scenario: testPostListenerResource
+* def listenerUrl = nbiBaseUrl + "/test/listener"
+Given path 'test/listener'
+When method delete
+Then status 204
+Given path 'hub'
+And header Target = 'http://localhost:8080/nbi/api/v4'
+And request { callback : '#(listenerUrl)' , query : 'eventType = ServiceOrderCreationNotification' }
+When method post
+Then status 201
+And def hubId = $.id
+Given path 'serviceOrder'
+And request serviceOrderData[17]
+And header Target = 'http://localhost:8080/nbi/api/v4'
+When method post
+Then status 201
+And def serviceOrderId = $.id
+Given path 'test/listener'
+And params {serviceOrderId : '#(serviceOrderId)'}
+And retry until responseStatus == 200
+When method get
+And assert response.length == 1
+And match $[0] contains { eventId : '#notnull' , eventType : 'ServiceOrderCreationNotification' , eventDate : '#notnull' , event :'#notnull'}
+And def eventId = $[0].eventId
+And def eventDate = $[0].eventDate
+And call checkDateFormat(eventDate)
+Given path 'serviceOrder',serviceOrderId
+When method delete
+Then status 204
+Given path 'hub',hubId
+And header Target = 'http://localhost:8080/nbi/api/v4'
+When method delete
+Then status 204
+Given path 'test/listener',eventId
+When method delete
+Then status 204
\ No newline at end of file