ca00849820e91dbfb9308ce9a4edacc7e548baae
[policy/apex-pdp.git] /
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.plugins.event.carrier.restclient;
23
24 import java.util.Arrays;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.regex.Matcher;
28 import java.util.regex.Pattern;
29 import javax.ws.rs.core.MultivaluedHashMap;
30 import javax.ws.rs.core.MultivaluedMap;
31 import org.onap.policy.apex.service.parameters.carriertechnology.CarrierTechnologyParameters;
32 import org.onap.policy.common.parameters.GroupValidationResult;
33 import org.onap.policy.common.parameters.ValidationStatus;
34 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
35
36 /**
37  * Apex parameters for REST as an event carrier technology with Apex as a REST client.
38  *
39  * <p>The parameters for this plugin are:
40  * <ol>
41  * <li>url: The URL that the Apex Rest client will connect to over REST for event reception or event sending. This
42  * parameter is mandatory.
43  * <li>httpMethod: The HTTP method to use when sending events over REST, legal values are POST (default) and PUT. When
44  * receiving events, the REST client plugin always uses the HTTP GET method.
45  * </ol>
46  *
47  * @author Joss Armstrong (joss.armstrong@ericsson.com)
48  */
49 public class RestClientCarrierTechnologyParameters extends CarrierTechnologyParameters {
50     /** The supported HTTP methods. */
51     public enum HttpMethod {
52         GET, PUT, POST, DELETE
53     }
54
55     /** The label of this carrier technology. */
56     public static final String RESTCLIENT_CARRIER_TECHNOLOGY_LABEL = "RESTCLIENT";
57
58     /** The producer plugin class for the REST carrier technology. */
59     public static final String RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS = ApexRestClientProducer.class.getName();
60
61     /** The consumer plugin class for the REST carrier technology. */
62     public static final String RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS = ApexRestClientConsumer.class.getName();
63
64     // Commonly occurring strings
65     private static final String HTTP_HEADERS = "httpHeaders";
66
67     private String url = null;
68     private HttpMethod httpMethod = null;
69     private String[][] httpHeaders = null;
70     private static final Pattern patternProperKey = Pattern.compile("(?<=\\{)[^}]*(?=\\})");
71     private static final Pattern patternErrorKey = Pattern.compile(
72         "(\\{[^\\{}]*.?\\{)|(\\{[^\\{}]*$)|(\\}[^\\{}]*.?\\})|(^[^\\{}]*.?\\})|\\{\\s*\\}");
73
74     /**
75      * Constructor to create a REST carrier technology parameters instance and register the instance with the parameter
76      * service.
77      */
78     public RestClientCarrierTechnologyParameters() {
79         super();
80
81         // Set the carrier technology properties for the web socket carrier technology
82         this.setLabel(RESTCLIENT_CARRIER_TECHNOLOGY_LABEL);
83         this.setEventProducerPluginClass(RESTCLIENT_EVENT_PRODUCER_PLUGIN_CLASS);
84         this.setEventConsumerPluginClass(RESTCLIENT_EVENT_CONSUMER_PLUGIN_CLASS);
85
86     }
87
88     /**
89      * Gets the URL for the REST request.
90      *
91      * @return the URL
92      */
93     public String getUrl() {
94         return url;
95     }
96
97     /**
98      * Sets the URL for the REST request.
99      *
100      * @param incomingUrl the URL
101      */
102     public void setUrl(final String incomingUrl) {
103         this.url = incomingUrl;
104     }
105
106     /**
107      * Gets the HTTP method to use for the REST request.
108      *
109      * @return the HTTP method
110      */
111     public HttpMethod getHttpMethod() {
112         return httpMethod;
113     }
114
115     /**
116      * Sets the HTTP method to use for the REST request.
117      *
118      * @param httpMethod the HTTP method
119      */
120     public void setHttpMethod(final HttpMethod httpMethod) {
121         this.httpMethod = httpMethod;
122     }
123
124     /**
125      * Check if http headers have been set for the REST request.
126      *
127      * @return true if headers have been set
128      */
129     public boolean checkHttpHeadersSet() {
130         return httpHeaders != null && httpHeaders.length > 0;
131     }
132
133     /**
134      * Gets the http headers for the REST request.
135      *
136      * @return the headers
137      */
138     public String[][] getHttpHeaders() {
139         return httpHeaders;
140     }
141
142     /**
143      * Gets the http headers for the REST request as a multivalued map.
144      *
145      * @return the headers
146      */
147     public MultivaluedMap<String, Object> getHttpHeadersAsMultivaluedMap() {
148         if (httpHeaders == null) {
149             return null;
150         }
151
152         // Load the HTTP headers into the map
153         MultivaluedMap<String, Object> httpHeaderMap = new MultivaluedHashMap<>();
154
155         for (String[] httpHeader : httpHeaders) {
156             httpHeaderMap.putSingle(httpHeader[0], httpHeader[1]);
157         }
158
159         return httpHeaderMap;
160     }
161
162     /**
163      * Sets the header for the REST request.
164      *
165      * @param httpHeaders the incoming HTTP headers
166      */
167     public void setHttpHeaders(final String[][] httpHeaders) {
168         this.httpHeaders = httpHeaders;
169     }
170
171     /**
172      * Get the tag for the REST Producer Properties.
173      *
174      * @return set of the tags
175      */
176     public Set<String> getKeysFromUrl() {
177         Matcher matcher = patternProperKey.matcher(this.url);
178         Set<String> key = new HashSet<>();
179         while (matcher.find()) {
180             key.add(matcher.group());
181         }
182         return key;
183     }
184
185     /**
186      * Validate tags in url.
187      * http://www.blah.com/{par1/somethingelse (Missing end tag) use  {[^\\{}]*$
188      * http://www.blah.com/{par1/{some}thingelse (Nested tag) use {[^}]*{
189      * http://www.blah.com/{par1}/some}thingelse (Missing start tag1) use }[^{}]*.}
190      * http://www.blah.com/par1}/somethingelse (Missing start tag2) use }[^{}]*}
191      * http://www.blah.com/{}/somethingelse (Empty tag) use {[\s]*}
192      *
193      * @return if url is legal
194      */
195     public boolean validateTagInUrl() {
196         // Check url tag syntax error
197         Matcher matcher = patternErrorKey.matcher(this.url);
198         return (!matcher.find());
199     }
200
201     /**
202      * {@inheritDoc}.
203      */
204     @Override
205     public GroupValidationResult validate() {
206         final GroupValidationResult result = super.validate();
207
208         // Check if the URL has been set for event output
209         if (getUrl() == null) {
210             result.setResult("url", ValidationStatus.INVALID,
211                 "no URL has been set for event sending on REST client");
212         }
213
214         if (httpHeaders == null) {
215             return result;
216         }
217
218         for (String[] httpHeader : httpHeaders) {
219             if (httpHeader == null) {
220                 result.setResult(HTTP_HEADERS, ValidationStatus.INVALID, "HTTP header array entry is null");
221             } else if (httpHeader.length != 2) {
222                 result.setResult(HTTP_HEADERS, ValidationStatus.INVALID,
223                                 "HTTP header array entries must have one key and one value: "
224                                                 + Arrays.deepToString(httpHeader));
225             } else if (!ParameterValidationUtils.validateStringParameter(httpHeader[0])) {
226                 result.setResult(HTTP_HEADERS, ValidationStatus.INVALID,
227                                 "HTTP header key is null or blank: " + Arrays.deepToString(httpHeader));
228             } else if (!ParameterValidationUtils.validateStringParameter(httpHeader[1])) {
229                 result.setResult(HTTP_HEADERS, ValidationStatus.INVALID,
230                                 "HTTP header value is null or blank: " + Arrays.deepToString(httpHeader));
231             }
232         }
233
234         if (!validateTagInUrl()) {
235             result.setResult("url", ValidationStatus.INVALID,
236                     "no proper URL has been set for event sending on REST client");
237         }
238         return result;
239     }
240
241     /**
242      * {@inheritDoc}.
243      */
244     @Override
245     public String toString() {
246         return "RestClientCarrierTechnologyParameters [url=" + url + ", httpMethod=" + httpMethod + ", httpHeaders="
247                         + Arrays.deepToString(httpHeaders) + "]";
248     }
249 }