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 + 5 files changed, 184 insertions(+), 15 deletions(-) (limited to 'plugins/plugins-event/plugins-event-carrier/plugins-event-carrier-restclient') 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. -- cgit 1.2.3-korg