From 99913f91b06abedd84e3837f836461cf8a14c0d7 Mon Sep 17 00:00:00 2001 From: "ning.xi" Date: Thu, 11 Jul 2019 07:31:31 +0000 Subject: Make URL configurable in REST Requestor/Client Change-Id: Ifb9870636996d1af786f05fcef7aa811d6f57532 Issue-ID: POLICY-1743 Signed-off-by: ning.xi --- .../carrier/restclient/ApexRestClientProducer.java | 34 ++++++++-- .../RestClientCarrierTechnologyParameters.java | 47 +++++++++++++- .../restclient/ApexRestClientProducerTest.java | 59 ++++++++++++++++- .../RestClientCarrierTechnologyParametersTest.java | 58 +++++++++++++++-- .../restclient/SupportApexEventReceiver.java | 1 + .../carrier/restrequestor/ApexRestRequest.java | 17 ++++- .../restrequestor/ApexRestRequestorConsumer.java | 40 +++++++++--- .../restrequestor/ApexRestRequestorProducer.java | 4 +- .../RestRequestorCarrierTechnologyParameters.java | 47 +++++++++++++- .../carrier/restrequestor/ApexRestRequestTest.java | 14 ++-- .../ApexRestRequestorConsumerTest.java | 75 ++++++++++++++++++++-- ...stRequestorCarrierTechnologyParametersTest.java | 56 +++++++++++++++- 12 files changed, 415 insertions(+), 37 deletions(-) (limited to 'plugins') diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java index 6739d82a9..822ac46a2 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducer.java @@ -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 names = restProducerProperties.getKeysFromUrl(); + Set 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)); } } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParameters.java index 258c01d3f..ca0084982 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParameters.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/main/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParameters.java @@ -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. @@ -21,10 +22,12 @@ 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 getKeysFromUrl() { + Matcher matcher = patternProperKey.matcher(this.url); + Set 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; } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducerTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducerTest.java index 8ef0ec95c..d57bdd769 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducerTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/ApexRestClientProducerTest.java @@ -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"); } } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParametersTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParametersTest.java index 3d0c9b73f..f982059f7 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParametersTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/RestClientCarrierTechnologyParametersTest.java @@ -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 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()); + + } } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/SupportApexEventReceiver.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/SupportApexEventReceiver.java index 739a6660a..717d1e9cb 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/SupportApexEventReceiver.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient/src/test/java/org/onap/policy/apex/plugins/event/carrier/restclient/SupportApexEventReceiver.java @@ -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. diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java index 8ada5e617..08467f0bd 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequest.java @@ -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. * diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java index 776440232..db4eacb4b 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumer.java @@ -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 names = restConsumerProperties.getKeysFromUrl(); + Set 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: diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java index bbe61f3fe..59a9ac971 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorProducer.java @@ -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 { diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParameters.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParameters.java index 9bff0e2e4..d583b790e 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParameters.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/main/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParameters.java @@ -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. @@ -21,6 +22,10 @@ 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 getKeysFromUrl() { + Matcher matcher = patternProperKey.matcher(this.url); + Set 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; } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestTest.java index 559d2dba8..dc55c06f7 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestTest.java @@ -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()); diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumerTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumerTest.java index 44e020381..ac1af67dd 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumerTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/ApexRestRequestorConsumerTest.java @@ -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"); + } + } } diff --git a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParametersTest.java b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParametersTest.java index 7be42e264..68c6811b4 100644 --- a/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParametersTest.java +++ b/plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restrequestor/src/test/java/org/onap/policy/apex/plugins/event/carrier/restrequestor/RestRequestorCarrierTechnologyParametersTest.java @@ -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 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()); + } + } -- cgit 1.2.3-korg