Make URL configurable in REST Requestor/Client 78/90878/10
authorning.xi <ning.xi@est.tech>
Thu, 11 Jul 2019 07:31:31 +0000 (07:31 +0000)
committerning.xi <ning.xi@est.tech>
Thu, 11 Jul 2019 07:31:31 +0000 (07:31 +0000)
Change-Id: Ifb9870636996d1af786f05fcef7aa811d6f57532
Issue-ID: POLICY-1743
Signed-off-by: ning.xi <ning.xi@est.tech>
12 files changed:
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParameters.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducerTest.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParametersTest.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/SupportApexEventReceiver.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParameters.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestTest.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumerTest.java
plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParametersTest.java

index 6739d82..822ac46 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,6 +24,9 @@ package org.onap.policy.apex.plugins.event.carrier.restclient;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.Properties;
+import java.util.Set;
+import java.util.Optional;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
@@ -36,6 +40,8 @@ import org.onap.policy.apex.service.engine.event.PeeredReference;
 import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.parameters.ParameterException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -134,12 +140,28 @@ public class ApexRestClientProducer implements ApexEventProducer {
             synchronousEventCache.removeCachedEventToApexIfExists(executionId);
         }
 
+        String untaggedUrl = restProducerProperties.getUrl();
+        if (executionProperties != null) {
+            Set<String> names = restProducerProperties.getKeysFromUrl();
+            Set<String> inputProperty = executionProperties.stringPropertyNames();
+
+            names.stream().map(key -> Optional.of(key)).forEach(op -> {
+                op.filter(str -> inputProperty.contains(str))
+                    .orElseThrow(() -> new ApexEventRuntimeException(
+                        "key\"" + op.get() + "\"specified on url \"" + restProducerProperties.getUrl() +
+                        "\"not found in execution properties passed by the current policy"));
+            });
+
+            untaggedUrl = names.stream().reduce(untaggedUrl,
+                (acc, str) -> acc.replace("{" + str + "}", (String) executionProperties.get(str)));
+        }
+
         // Send the event as a REST request
-        final Response response = sendEventAsRestRequest((String) event);
+        final Response response = sendEventAsRestRequest(untaggedUrl, (String) event);
 
         // Check that the request worked
         if (response.getStatus() != Response.Status.OK.getStatusCode()) {
-            final String errorMessage = "send of event to URL \"" + restProducerProperties.getUrl() + "\" using HTTP \""
+            final String errorMessage = "send of event to URL \"" + untaggedUrl + "\" using HTTP \""
                     + restProducerProperties.getHttpMethod() + "\" failed with status code " + response.getStatus()
                     + " and message \"" + response.readEntity(String.class) + "\", event:\n" + event;
             LOGGER.warn(errorMessage);
@@ -148,7 +170,7 @@ public class ApexRestClientProducer implements ApexEventProducer {
 
         if (LOGGER.isTraceEnabled()) {
             LOGGER.trace("event sent from engine using {} to URL {} with HTTP {} : {} and response {} ", this.name,
-                    restProducerProperties.getUrl(), restProducerProperties.getHttpMethod(), event, response);
+                untaggedUrl, restProducerProperties.getHttpMethod(), event, response);
         }
     }
 
@@ -167,13 +189,13 @@ public class ApexRestClientProducer implements ApexEventProducer {
      * @param event the event to send
      * @return the response to the JSON request
      */
-    private Response sendEventAsRestRequest(final String event) {
+    private Response sendEventAsRestRequest(final String untaggedUrl, final String event) {
         // We have already checked that it is a PUT or POST request
         if (RestClientCarrierTechnologyParameters.HttpMethod.POST.equals(restProducerProperties.getHttpMethod())) {
-            return client.target(restProducerProperties.getUrl()).request("application/json")
+            return client.target(untaggedUrl).request("application/json")
                     .headers(restProducerProperties.getHttpHeadersAsMultivaluedMap()).post(Entity.json(event));
         } else {
-            return client.target(restProducerProperties.getUrl()).request("application/json")
+            return client.target(untaggedUrl).request("application/json")
                     .headers(restProducerProperties.getHttpHeadersAsMultivaluedMap()).put(Entity.json(event));
         }
     }
index 258c01d..ca00849 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 package org.onap.policy.apex.plugins.event.carrier.restclient;
 
 import java.util.Arrays;
-
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
-
 import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
 import org.onap.policy.common.parameters.GroupValidationResult;
 import org.onap.policy.common.parameters.ValidationStatus;
@@ -64,6 +67,9 @@ public class RestClientCarrierTechnologyParameters extends CarrierTechnologyPara
     private String url = null;
     private HttpMethod httpMethod = null;
     private String[][] httpHeaders = null;
+    private static final Pattern patternProperKey = Pattern.compile("(?<=\\{)[^}]*(?=\\})");
+    private static final Pattern patternErrorKey = Pattern.compile(
+        "(\\{[^\\{}]*.?\\{)|(\\{[^\\{}]*$)|(\\}[^\\{}]*.?\\})|(^[^\\{}]*.?\\})|\\{\\s*\\}");
 
     /**
      * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
@@ -162,6 +168,36 @@ public class RestClientCarrierTechnologyParameters extends CarrierTechnologyPara
         this.httpHeaders = httpHeaders;
     }
 
+    /**
+     * Get the tag for the REST Producer Properties.
+     *
+     * @return set of the tags
+     */
+    public Set<String> getKeysFromUrl() {
+        Matcher matcher = patternProperKey.matcher(this.url);
+        Set<String> key = new HashSet<>();
+        while (matcher.find()) {
+            key.add(matcher.group());
+        }
+        return key;
+    }
+
+    /**
+     * Validate tags in url.
+     * http://www.blah.com/{par1/somethingelse (Missing end tag) use  {[^\\{}]*$
+     * http://www.blah.com/{par1/{some}thingelse (Nested tag) use {[^}]*{
+     * http://www.blah.com/{par1}/some}thingelse (Missing start tag1) use }[^{}]*.}
+     * http://www.blah.com/par1}/somethingelse (Missing start tag2) use }[^{}]*}
+     * http://www.blah.com/{}/somethingelse (Empty tag) use {[\s]*}
+     *
+     * @return if url is legal
+     */
+    public boolean validateTagInUrl() {
+        // Check url tag syntax error
+        Matcher matcher = patternErrorKey.matcher(this.url);
+        return (!matcher.find());
+    }
+
     /**
      * {@inheritDoc}.
      */
@@ -171,7 +207,8 @@ public class RestClientCarrierTechnologyParameters extends CarrierTechnologyPara
 
         // Check if the URL has been set for event output
         if (getUrl() == null) {
-            result.setResult("url", ValidationStatus.INVALID, "no URL has been set for event sending on REST client");
+            result.setResult("url", ValidationStatus.INVALID,
+                "no URL has been set for event sending on REST client");
         }
 
         if (httpHeaders == null) {
@@ -194,6 +231,10 @@ public class RestClientCarrierTechnologyParameters extends CarrierTechnologyPara
             }
         }
 
+        if (!validateTagInUrl()) {
+            result.setResult("url", ValidationStatus.INVALID,
+                    "no proper URL has been set for event sending on REST client");
+        }
         return result;
     }
 
index 8ef0ec9..d57bdd7 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -41,9 +42,13 @@ import org.onap.policy.apex.service.engine.event.SynchronousEventCache;
 import org.onap.policy.apex.service.engine.event.impl.filecarrierplugin.consumer.ApexFileEventConsumer;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
+import org.onap.policy.common.parameters.GroupValidationResult;
+import org.onap.policy.common.parameters.ParameterException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.util.Properties;
+
 /**
  * Test the ApexRestClientProducer class.
  *
@@ -174,7 +179,7 @@ public class ApexRestClientProducerTest {
     }
 
     @Test
-    public void testApexRestClientProducerPostEvent() {
+    public void testApexRestClientProducerPostEventFail() {
         MockitoAnnotations.initMocks(this);
 
         ApexRestClientProducer arcp = new ApexRestClientProducer();
@@ -202,10 +207,60 @@ public class ApexRestClientProducerTest {
         Mockito.doReturn(targetMock).when(httpClientMock).target(rcctp.getUrl());
         arcp.setClient(httpClientMock);
 
+        //test property not found
+        rcctp.setUrl("http://some.place2.that.{key}.not/{tag}and.again.{tag}");
+        Properties properties = new Properties();
+        properties.put("tag", "exist");
         try {
-            arcp.sendEvent(123, null, "EventName", "This is an Event");
+            arcp.sendEvent(123, properties, "EventName", "This is an Event");
             arcp.stop();
+            fail("test should throw an exception");
         } catch (Exception e) {
+            assertEquals(
+                    "key\"key\"specified on url "
+                            + "\"http://some.place2.that.{key}.not/{tag}and.again.{tag}\"not found "
+                            + "in execution properties passed by the current policy",
+                    e.getMessage());
+        }
+    }
+
+    @Test
+    public void testApexRestClientProducerPostEventOK() {
+        MockitoAnnotations.initMocks(this);
+
+        ApexRestClientProducer arcp = new ApexRestClientProducer();
+        assertNotNull(arcp);
+
+        EventHandlerParameters producerParameters = new EventHandlerParameters();
+        RestClientCarrierTechnologyParameters rcctp = new RestClientCarrierTechnologyParameters();
+        producerParameters.setCarrierTechnologyParameters(rcctp);
+
+        rcctp.setHttpMethod(RestClientCarrierTechnologyParameters.HttpMethod.PUT);
+        try {
+            arcp.init("RestClientConsumer", producerParameters);
+            assertEquals(RestClientCarrierTechnologyParameters.HttpMethod.PUT, rcctp.getHttpMethod());
+
+            assertEquals("RestClientConsumer", arcp.getName());
+        } catch (ApexEventException e) {
+            fail("test should not throw an exception");
+        }
+
+        System.out.println("fail test");
+        rcctp.setUrl("http://some.place.{key}.does.not/{tag}");
+        Properties properties = new Properties();
+        properties.put("tag", "exist");
+        properties.put("key", "that");
+        Mockito.doReturn(Response.Status.OK.getStatusCode()).when(responseMock).getStatus();
+        Mockito.doReturn(responseMock).when(builderMock).put(Mockito.any());
+        Mockito.doReturn(builderMock).when(targetMock).request("application/json");
+        Mockito.doReturn(builderMock).when(builderMock).headers(Mockito.any());
+        Mockito.doReturn(targetMock).when(httpClientMock).target("http://some.place.that.does.not/exist");
+        arcp.setClient(httpClientMock);
+
+        try {
+            arcp.sendEvent(123, properties, "EventName", "This is an Event");
+            arcp.stop();
+        } catch (Exception ex) {
             fail("test should not throw an exception");
         }
     }
index 3d0c9b7..f982059 100644 (file)
@@ -1,19 +1,20 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * 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.
- * 
+ *
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
@@ -31,6 +32,8 @@ import org.onap.policy.apex.service.parameters.ApexParameterHandler;
 import org.onap.policy.apex.service.parameters.ApexParameters;
 import org.onap.policy.common.parameters.ParameterException;
 
+import java.util.Set;
+
 /**
  * Test REST Requestor carrier technology parameters.
  */
@@ -102,7 +105,7 @@ public class RestClientCarrierTechnologyParametersTest {
             assertEquals("bbb", rrctp1.getHttpHeadersAsMultivaluedMap().get("aaa").get(0));
             assertEquals("ddd", rrctp1.getHttpHeadersAsMultivaluedMap().get("ccc").get(0));
             assertEquals("fff", rrctp1.getHttpHeadersAsMultivaluedMap().get("eee").get(0));
-            
+
             rrctp1.setHttpHeaders(null);
             assertEquals(null, rrctp1.getHttpHeadersAsMultivaluedMap());
         } catch (ParameterException pe) {
@@ -146,4 +149,51 @@ public class RestClientCarrierTechnologyParametersTest {
                         + "[url=http://some.where, httpMethod=DELETE, httpHeaders=[[aaa, bbb], [ccc, ddd]]]",
                         rrctp.toString());
     }
+
+    @Test
+    public void testUrlValidation() {
+        RestClientCarrierTechnologyParameters rrctp =
+                new RestClientCarrierTechnologyParameters();
+
+        rrctp.setUrl("http://some.where.no.tag.in.url");
+        assertEquals("http://some.where.no.tag.in.url", rrctp.getUrl());
+
+        String[][] httpHeaders = new String[2][2];
+        httpHeaders[0][0] = "aaa";
+        httpHeaders[0][1] = "bbb";
+        httpHeaders[1][0] = "ccc";
+        httpHeaders[1][1] = "ddd";
+
+        rrctp.setHttpHeaders(httpHeaders);
+        assertEquals("aaa", rrctp.getHttpHeaders()[0][0]);
+        assertEquals("bbb", rrctp.getHttpHeaders()[0][1]);
+        assertEquals("ccc", rrctp.getHttpHeaders()[1][0]);
+        assertEquals("ddd", rrctp.getHttpHeaders()[1][1]);
+
+        assertEquals(true, rrctp.validateTagInUrl());
+
+        rrctp.setUrl("http://{place}.{that}/is{that}.{one}");
+        assertEquals(true, rrctp.validateTagInUrl());
+
+        Set<String> keymap = rrctp.getKeysFromUrl();
+        assertEquals(true, keymap.contains("place"));
+        assertEquals(true, keymap.contains("that"));
+        assertEquals(true, keymap.contains("one"));
+
+        rrctp.setUrl("http://{place.{that}/{is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{is}.{not}/{what}.{exist");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://place.that/is.not/what.{exist");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://place}.{that}/{is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{ }.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+
+    }
 }
index 739a666..717d1e9 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
index 8ada5e6..08467f0 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -20,6 +21,8 @@
 
 package org.onap.policy.apex.plugins.event.carrier.restrequestor;
 
+import java.util.Properties;
+
 /**
  * This class holds a record of a REST request for the REST requestor plugin.
  *
@@ -29,6 +32,7 @@ public class ApexRestRequest {
     private long executionId;
     private String eventName;
     private Object event;
+    private Properties executionProperties;
     private long timestamp;
 
     /**
@@ -38,8 +42,10 @@ public class ApexRestRequest {
      * @param eventName the event name
      * @param event the event
      */
-    public ApexRestRequest(final long executionId, final String eventName, final Object event) {
+    public ApexRestRequest(final long executionId, final Properties executionProperties,
+            final String eventName, final Object event) {
         this.executionId = executionId;
+        this.executionProperties = executionProperties;
         this.eventName = eventName;
         this.event = event;
     }
@@ -71,6 +77,15 @@ public class ApexRestRequest {
         return event;
     }
 
+    /**
+     * Gets the executionProperties.
+     *
+     * @return the executionProperties
+     */
+    public Properties getExecutionProperties() {
+        return executionProperties;
+    }
+
     /**
      * Gets the timestamp.
      *
index 7764402..db4eacb 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,11 +27,15 @@ import java.util.Arrays;
 import java.util.EnumMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import java.util.Optional;
 import java.util.Map.Entry;
 import java.util.concurrent.BlockingQueue;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
 
 import javax.ws.rs.client.Client;
 import javax.ws.rs.client.ClientBuilder;
@@ -98,6 +103,8 @@ public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
     // The number of the next request runner thread
     private static long nextRequestRunnerThreadNo = 0;
 
+    private String untaggedUrl = null;
+
     @Override
     public void init(final String consumerName, final EventHandlerParameters consumerParameters,
                     final ApexEventReceiver incomingEventReceiver) throws ApexEventException {
@@ -240,6 +247,23 @@ public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
                     continue;
                 }
 
+                Properties inputExecutionProperties = restRequest.getExecutionProperties();
+                untaggedUrl = restConsumerProperties.getUrl();
+                if (inputExecutionProperties != null) {
+                    Set<String> names = restConsumerProperties.getKeysFromUrl();
+                    Set<String> inputProperty = inputExecutionProperties.stringPropertyNames();
+
+                    names.stream().map(key -> Optional.of(key)).forEach(op -> {
+                        op.filter(str -> inputProperty.contains(str))
+                                .orElseThrow(() -> new ApexEventRuntimeException(
+                                        "key\"" + op.get() + "\"specified on url \"" + restConsumerProperties.getUrl() +
+                                                "\"not found in execution properties passed by the current policy"));
+                    });
+
+                    untaggedUrl = names.stream().reduce(untaggedUrl,
+                            (acc, str) -> acc.replace("{" + str + "}", (String) inputExecutionProperties.get(str)));
+                }
+
                 // Set the time stamp of the REST request
                 restRequest.setTimestamp(System.currentTimeMillis());
 
@@ -331,12 +355,12 @@ public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
 
             try {
                 // Execute the REST request
-                final Response response = sendEventAsRestRequest();
+                final Response response = sendEventAsRestRequest(untaggedUrl);
 
                 // Check that the event request worked
                 if (!Response.Status.Family.familyOf(response.getStatus()).equals(Response.Status.Family.SUCCESSFUL)) {
                     final String errorMessage = "reception of response to \"" + request + "\" from URL \""
-                                    + restConsumerProperties.getUrl() + "\" failed with status code "
+                                    + untaggedUrl + "\" failed with status code "
                                     + response.getStatus() + " and message \"" + response.readEntity(String.class)
                                     + "\"";
                     throw new ApexEventRuntimeException(errorMessage);
@@ -348,7 +372,7 @@ public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
                 // Check there is content
                 if (eventJsonString == null || eventJsonString.trim().length() == 0) {
                     final String errorMessage = "received an enpty response to \"" + request + "\" from URL \""
-                                    + restConsumerProperties.getUrl() + "\"";
+                                    + untaggedUrl + "\"";
                     throw new ApexEventRuntimeException(errorMessage);
                 }
 
@@ -379,24 +403,24 @@ public class ApexRestRequestorConsumer implements ApexEventConsumer, Runnable {
          *
          * @return the response to the REST request
          */
-        public Response sendEventAsRestRequest() {
+        public Response sendEventAsRestRequest(String untaggedUrl) {
             switch (restConsumerProperties.getHttpMethod()) {
                 case GET:
-                    return client.target(restConsumerProperties.getUrl()).request(APPLICATION_JSON)
+                    return client.target(untaggedUrl).request(APPLICATION_JSON)
                                     .headers(restConsumerProperties.getHttpHeadersAsMultivaluedMap()).get();
 
                 case PUT:
-                    return client.target(restConsumerProperties.getUrl()).request(APPLICATION_JSON)
+                    return client.target(untaggedUrl).request(APPLICATION_JSON)
                                     .headers(restConsumerProperties.getHttpHeadersAsMultivaluedMap())
                                     .put(Entity.json(request.getEvent()));
 
                 case POST:
-                    return client.target(restConsumerProperties.getUrl()).request(APPLICATION_JSON)
+                    return client.target(untaggedUrl).request(APPLICATION_JSON)
                                     .headers(restConsumerProperties.getHttpHeadersAsMultivaluedMap())
                                     .post(Entity.json(request.getEvent()));
 
                 case DELETE:
-                    return client.target(restConsumerProperties.getUrl()).request(APPLICATION_JSON)
+                    return client.target(untaggedUrl).request(APPLICATION_JSON)
                                     .headers(restConsumerProperties.getHttpHeadersAsMultivaluedMap()).delete();
 
                 default:
index bbe61f3..59a9ac9 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -159,7 +160,8 @@ public class ApexRestRequestorProducer implements ApexEventProducer {
 
             // Use the consumer to handle this event
             final ApexRestRequestorConsumer restRequstConsumer = (ApexRestRequestorConsumer) consumer;
-            restRequstConsumer.processRestRequest(new ApexRestRequest(executionId, eventName, event));
+            restRequstConsumer.processRestRequest(new ApexRestRequest(
+                executionId, executionProperties, eventName, event));
 
             eventsSent++;
         } else {
index 9bff0e2..d583b79 100644 (file)
@@ -1,6 +1,7 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 package org.onap.policy.apex.plugins.event.carrier.restrequestor;
 
 import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.ws.rs.core.MultivaluedHashMap;
 import javax.ws.rs.core.MultivaluedMap;
@@ -78,8 +83,12 @@ public class RestRequestorCarrierTechnologyParameters extends CarrierTechnologyP
     private HttpMethod httpMethod = null;
     private String[][] httpHeaders = null;
 
+    private static final Pattern patternProperKey = Pattern.compile("(?<=\\{)[^}]*(?=\\})");
+    private static final Pattern patternErrorKey = Pattern.compile(
+        "(\\{[^\\{}]*.?\\{)|(\\{[^\\{}]*$)|(\\}[^\\{}]*.?\\})|(^[^\\{}]*.?\\})|\\{\\s*\\}");
+
     /**
-     * Constructor to create a REST carrier technology parameters instance and regiaaaster the instance with the
+     * Constructor to create a REST carrier technology parameters instance and register the instance with the
      * parameter service.
      */
     public RestRequestorCarrierTechnologyParameters() {
@@ -174,6 +183,36 @@ public class RestRequestorCarrierTechnologyParameters extends CarrierTechnologyP
         this.httpHeaders = httpHeaders;
     }
 
+    /**
+     * Get the tag for the REST Producer Properties.
+     *
+     * @return set of the tags
+     */
+    public Set<String> getKeysFromUrl() {
+        Matcher matcher = patternProperKey.matcher(this.url);
+        Set<String> key = new HashSet<>();
+        while (matcher.find()) {
+            key.add(matcher.group());
+        }
+        return key;
+    }
+
+    /**
+     * Validate tags in url.
+     * http://www.blah.com/{par1/somethingelse (Missing end tag) use  {[^\\{}]*$
+     * http://www.blah.com/{par1/{some}thingelse (Missing end tag2) use {[^}]*{
+     * http://www.blah.com/{par1}/some}thingelse (Missing start tag1) use }[^{}]*.}
+     * http://www.blah.com/par1}/somethingelse (Missing start tag2) use }[^{}]*}
+     * http://www.blah.com/{}/somethingelse (Empty tag) use {[\s]*}
+     *
+     * @return if url is legal
+     */
+    public boolean validateTagInUrl() {
+        // Check url tag syntax error
+        Matcher matcher = patternErrorKey.matcher(this.url);
+        return (!matcher.find());
+    }
+
     /**
      * {@inheritDoc}.
      */
@@ -201,6 +240,12 @@ public class RestRequestorCarrierTechnologyParameters extends CarrierTechnologyP
             }
         }
 
+        if (!validateTagInUrl()) {
+            result.setResult("url", ValidationStatus.INVALID,
+                "no proper URL has been set for event sending on REST client");
+        }
+
+
         return result;
     }
 
index 559d2db..dc55c06 100644 (file)
@@ -1,19 +1,20 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * 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.
- * 
+ *
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
@@ -24,6 +25,8 @@ import static org.junit.Assert.assertEquals;
 
 import org.junit.Test;
 
+import java.util.Properties;
+
 /**
  * Test the ApexRestRequest class.
  */
@@ -34,11 +37,14 @@ public class ApexRestRequestTest {
         final String eventName = "EventName";
         final String eventString = "The Event String";
 
-        ApexRestRequest rr = new ApexRestRequest(1, eventName, eventString);
+        Properties properties = new Properties();
+        properties.put("key", "value");
+        ApexRestRequest rr = new ApexRestRequest(1, properties, eventName, eventString);
 
         assertEquals(1, rr.getExecutionId());
         assertEquals(eventName, rr.getEventName());
         assertEquals(eventString, rr.getEvent());
+        assertEquals(properties, rr.getExecutionProperties());
 
         rr.setTimestamp(1234567);
         assertEquals(1234567, rr.getTimestamp());
index 44e0203..ac1af67 100644 (file)
@@ -1,19 +1,20 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * 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.
- * 
+ *
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
@@ -28,9 +29,12 @@ import org.junit.Test;
 import org.onap.policy.apex.core.infrastructure.threading.ThreadUtilities;
 import org.onap.policy.apex.service.engine.event.ApexEventException;
 import org.onap.policy.apex.service.engine.event.ApexEventReceiver;
+import org.onap.policy.apex.service.engine.event.ApexEventRuntimeException;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerParameters;
 import org.onap.policy.apex.service.parameters.eventhandler.EventHandlerPeeredMode;
 
+import java.util.Properties;
+
 /**
  * Test the ApexRestRequestorConsumer class.
  *
@@ -125,7 +129,7 @@ public class ApexRestRequestorConsumerTest {
         try {
             consumer.init(consumerName, consumerParameters, incomingEventReceiver);
             consumer.start();
-            ApexRestRequest request = new ApexRestRequest(123, "EventName", "Event body");
+            ApexRestRequest request = new ApexRestRequest(123, null,"EventName", "Event body");
             consumer.processRestRequest(request);
             ThreadUtilities.sleep(2000);
             consumer.stop();
@@ -134,4 +138,67 @@ public class ApexRestRequestorConsumerTest {
             fail("test should not throw an exception");
         }
     }
+
+    @Test
+    public void testApexRestRequestorConsumerUrlUpdate() {
+        ApexRestRequestorConsumer consumer = new ApexRestRequestorConsumer();
+        assertNotNull(consumer);
+
+        String consumerName = "ConsumerName";
+
+        EventHandlerParameters consumerParameters = new EventHandlerParameters();
+        ApexEventReceiver incomingEventReceiver = null;
+        RestRequestorCarrierTechnologyParameters rrctp = new RestRequestorCarrierTechnologyParameters();
+        consumerParameters.setCarrierTechnologyParameters(rrctp);
+        consumerParameters.setPeeredMode(EventHandlerPeeredMode.REQUESTOR, true);
+        rrctp.setHttpMethod(RestRequestorCarrierTechnologyParameters.HttpMethod.GET);
+
+        rrctp.setUrl("http://www.{site}.{site}.{net}");
+        consumerParameters.setPeerTimeout(EventHandlerPeeredMode.REQUESTOR, 2000);
+        Properties properties = new Properties();
+        properties.put("site", "onap");
+        properties.put("net", "org");
+        try {
+            consumer.init(consumerName, consumerParameters, incomingEventReceiver);
+            consumer.start();
+            ApexRestRequest request = new ApexRestRequest(123, properties,"EventName", "Event body");
+            consumer.processRestRequest(request);
+            ThreadUtilities.sleep(2000);
+            consumer.stop();
+            assertEquals(0, consumer.getEventsReceived());
+        } catch (Exception aee) {
+            fail("test should not throw an exception");
+        }
+    }
+
+    @Test
+    public void testApexRestRequestorConsumerUrlUpdateError() {
+        ApexRestRequestorConsumer consumer = new ApexRestRequestorConsumer();
+        assertNotNull(consumer);
+
+        String consumerName = "ConsumerName";
+
+        EventHandlerParameters consumerParameters = new EventHandlerParameters();
+        ApexEventReceiver incomingEventReceiver = null;
+        RestRequestorCarrierTechnologyParameters rrctp = new RestRequestorCarrierTechnologyParameters();
+        consumerParameters.setCarrierTechnologyParameters(rrctp);
+        consumerParameters.setPeeredMode(EventHandlerPeeredMode.REQUESTOR, true);
+        rrctp.setHttpMethod(RestRequestorCarrierTechnologyParameters.HttpMethod.GET);
+
+        rrctp.setUrl("http://www.{site}.{net}");
+        consumerParameters.setPeerTimeout(EventHandlerPeeredMode.REQUESTOR, 2000);
+        Properties properties = new Properties();
+        properties.put("site", "onap");
+        try {
+            consumer.init(consumerName, consumerParameters, incomingEventReceiver);
+            consumer.start();
+            ApexRestRequest request = new ApexRestRequest(123, properties,"EventName", "Event body");
+            consumer.processRestRequest(request);
+            ThreadUtilities.sleep(2000);
+            consumer.stop();
+            assertEquals(0, consumer.getEventsReceived());
+        } catch (Exception aee) {
+            fail("test should not throw an exception");
+        }
+    }
 }
index 7be42e2..68c6811 100644 (file)
@@ -1,19 +1,20 @@
 /*-
  * ============LICENSE_START=======================================================
  *  Copyright (C) 2018 Ericsson. All rights reserved.
+ *  Modifications Copyright (C) 2019 Nordix Foundation.
  * ================================================================================
  * 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.
- * 
+ *
  * SPDX-License-Identifier: Apache-2.0
  * ============LICENSE_END=========================================================
  */
@@ -31,6 +32,8 @@ import org.onap.policy.apex.service.parameters.ApexParameterHandler;
 import org.onap.policy.apex.service.parameters.ApexParameters;
 import org.onap.policy.common.parameters.ParameterException;
 
+import java.util.Set;
+
 /**
  * Test REST Requestor carrier technology parameters.
  */
@@ -143,4 +146,51 @@ public class RestRequestorCarrierTechnologyParametersTest {
                         + "[url=http://some.where, httpMethod=DELETE, httpHeaders=[[aaa, bbb], [ccc, ddd]]]",
                         rrctp.toString());
     }
+
+    @Test
+    public void testUrlValidation() {
+        RestRequestorCarrierTechnologyParameters rrctp =
+            new RestRequestorCarrierTechnologyParameters();
+
+        rrctp.setUrl("http://some.where.no.tag.in.url");
+        assertEquals("http://some.where.no.tag.in.url", rrctp.getUrl());
+
+        String[][] httpHeaders = new String[2][2];
+        httpHeaders[0][0] = "aaa";
+        httpHeaders[0][1] = "bbb";
+        httpHeaders[1][0] = "ccc";
+        httpHeaders[1][1] = "ddd";
+
+        rrctp.setHttpHeaders(httpHeaders);
+        assertEquals("aaa", rrctp.getHttpHeaders()[0][0]);
+        assertEquals("bbb", rrctp.getHttpHeaders()[0][1]);
+        assertEquals("ccc", rrctp.getHttpHeaders()[1][0]);
+        assertEquals("ddd", rrctp.getHttpHeaders()[1][1]);
+
+        assertEquals(true, rrctp.validateTagInUrl());
+
+        rrctp.setUrl("http://{place}.{that}/is{that}.{one}");
+        assertEquals(true, rrctp.validateTagInUrl());
+
+        Set<String> keymap = rrctp.getKeysFromUrl();
+        assertEquals(true, keymap.contains("place"));
+        assertEquals(true, keymap.contains("that"));
+        assertEquals(true, keymap.contains("one"));
+
+        rrctp.setUrl("http://{place.{that}/{is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{is}.{not}/{what}.{exist");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://place.that/is.not/what.{exist");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://place}.{that}/{is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/is}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{}.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+        rrctp.setUrl("http://{place}.{that}/{ }.{not}/{what}.{exist}");
+        assertEquals(false, rrctp.validateTagInUrl());
+    }
+
 }