aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVodafone <onap@vodafone.com>2019-03-25 17:38:23 +0530
committerMatthieu Geerebaert <matthieu.geerebaert@orange.com>2019-04-12 14:13:40 +0200
commitff5433e350678f5f45e8b2aa14cdb00f9cecfceb (patch)
tree002fc90357697b9b4bcfa96279731873a7b3bcc4
parent5ad4e649d9c634309447fda7b867719040c1fd56 (diff)
CCVPN (East-west Interface)
Change-Id: I11dbe477db3310ef054b2e894e8005b0f8e4be96 Issue-ID: EXTAPI-204 Co-authored-by: madhuri.verma@vodafone.com Signed-off-by: Vodafone <onap@vodafone.com>
-rw-r--r--docs/configuration/configuration.rst2
-rw-r--r--src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java10
-rw-r--r--src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java90
-rwxr-xr-xsrc/main/java/org/onap/nbi/apis/hub/HubResource.java59
-rw-r--r--src/main/java/org/onap/nbi/apis/hub/ListenerResource.java53
-rwxr-xr-xsrc/main/java/org/onap/nbi/apis/hub/model/Subscriber.java22
-rwxr-xr-xsrc/main/java/org/onap/nbi/apis/hub/model/Subscription.java23
-rwxr-xr-xsrc/main/java/org/onap/nbi/apis/hub/service/NotificationAspect.java9
-rw-r--r--src/main/java/org/onap/nbi/apis/listener/ListenerResourceTarget.java71
-rw-r--r--src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java3
-rw-r--r--src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java3
-rw-r--r--src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java107
-rw-r--r--src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java49
-rw-r--r--src/main/java/org/onap/nbi/commons/EWInterfaceUtils.java128
-rw-r--r--src/main/resources/application.properties5
-rw-r--r--src/test/resources/karatetest/data/Event.json13
-rw-r--r--src/test/resources/karatetest/data/subscriber.json4
-rw-r--r--src/test/resources/karatetest/features/02--ServiceOrder.feature27
-rw-r--r--src/test/resources/karatetest/features/03--Subscriber.feature36
-rw-r--r--src/test/resources/karatetest/features/05--ListenerResourceTestTarget.feature74
20 files changed, 419 insertions, 369 deletions
diff --git a/docs/configuration/configuration.rst b/docs/configuration/configuration.rst
index 6290691..a498e4d 100644
--- a/docs/configuration/configuration.rst
+++ b/docs/configuration/configuration.rst
@@ -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
diff --git a/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
index 0796c2f..8828321 100644
--- a/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
+++ b/src/main/java/org/onap/nbi/OnapComponentsUrlPaths.java
@@ -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
index 10d6f7c..0000000
--- a/src/main/java/org/onap/nbi/apis/hub/ExtApiClientForHub.java
+++ /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);
-
- }
-
- }
-}
-
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 28e1313..3f14b8a 100755
--- a/src/main/java/org/onap/nbi/apis/hub/HubResource.java
+++ b/src/main/java/org/onap/nbi/apis/hub/HubResource.java
@@ -13,19 +13,23 @@
*/
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
index aa236d1..0000000
--- a/src/main/java/org/onap/nbi/apis/hub/ListenerResource.java
+++ /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");
-
- }
- }
-}
diff --git a/src/main/java/org/onap/nbi/apis/hub/model/Subscriber.java b/src/main/java/org/onap/nbi/apis/hub/model/Subscriber.java
index ab2b05f..582b14b 100755
--- a/src/main/java/org/onap/nbi/apis/hub/model/Subscriber.java
+++ b/src/main/java/org/onap/nbi/apis/hub/model/Subscriber.java
@@ -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("="))
diff --git a/src/main/java/org/onap/nbi/apis/hub/model/Subscription.java b/src/main/java/org/onap/nbi/apis/hub/model/Subscription.java
index 34e23e1..646d39b 100755
--- a/src/main/java/org/onap/nbi/apis/hub/model/Subscription.java
+++ b/src/main/java/org/onap/nbi/apis/hub/model/Subscription.java
@@ -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()
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 3033404..cd242e8 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,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
index 0000000..8b8e50f
--- /dev/null
+++ b/src/main/java/org/onap/nbi/apis/listener/ListenerResourceTarget.java
@@ -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();
+ }
+}
+
diff --git a/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
index 6484672..49b9f08 100644
--- a/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
+++ b/src/main/java/org/onap/nbi/apis/servicecatalog/ServiceSpecificationResource.java
@@ -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 {
diff --git a/src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java b/src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java
index cd46d74..eda6f96 100644
--- a/src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java
+++ b/src/main/java/org/onap/nbi/apis/serviceinventory/ServiceInventoryResource.java
@@ -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
index 7fd06e6..0000000
--- a/src/main/java/org/onap/nbi/apis/serviceorder/ExtApiClient.java
+++ /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);
- }
-
- }
-}
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 f8085b9..90d84a4 100644
--- a/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java
+++ b/src/main/java/org/onap/nbi/apis/serviceorder/ServiceOrderResource.java
@@ -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
index 0000000..24bf1fc
--- /dev/null
+++ b/src/main/java/org/onap/nbi/commons/EWInterfaceUtils.java
@@ -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;
+ }
+}
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 5b908b3..f290102 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -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
index 5887deb..0000000
--- a/src/test/resources/karatetest/data/Event.json
+++ /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
diff --git a/src/test/resources/karatetest/data/subscriber.json b/src/test/resources/karatetest/data/subscriber.json
index 14dfdb8..5fceb9f 100644
--- a/src/test/resources/karatetest/data/subscriber.json
+++ b/src/test/resources/karatetest/data/subscriber.json
@@ -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
diff --git a/src/test/resources/karatetest/features/02--ServiceOrder.feature b/src/test/resources/karatetest/features/02--ServiceOrder.feature
index 756a00e..4b4891d 100644
--- a/src/test/resources/karatetest/features/02--ServiceOrder.feature
+++ b/src/test/resources/karatetest/features/02--ServiceOrder.feature
@@ -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
diff --git a/src/test/resources/karatetest/features/03--Subscriber.feature b/src/test/resources/karatetest/features/03--Subscriber.feature
index ea8c24a..1d9bfdf 100644
--- a/src/test/resources/karatetest/features/03--Subscriber.feature
+++ b/src/test/resources/karatetest/features/03--Subscriber.feature
@@ -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
index 0000000..a42f9b7
--- /dev/null
+++ b/src/test/resources/karatetest/features/05--ListenerResourceTestTarget.feature
@@ -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