2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2016-2018 Ericsson. All rights reserved.
4 * Modifications Copyright (C) 2019-2021 Nordix Foundation.
5 * Modifications Copyright (C) 2021 AT&T Intellectual Property. All rights reserved.
6 * ================================================================================
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 * SPDX-License-Identifier: Apache-2.0
20 * ============LICENSE_END=========================================================
23 package org.onap.policy.apex.service.parameters.carriertechnology;
25 import java.util.Arrays;
26 import java.util.HashSet;
27 import java.util.List;
29 import java.util.regex.Matcher;
30 import java.util.regex.Pattern;
31 import java.util.regex.PatternSyntaxException;
32 import javax.ws.rs.core.MultivaluedHashMap;
33 import javax.ws.rs.core.MultivaluedMap;
36 import org.apache.commons.lang3.StringUtils;
37 import org.onap.policy.common.parameters.BeanValidationResult;
38 import org.onap.policy.common.parameters.ObjectValidationResult;
39 import org.onap.policy.common.parameters.ValidationResult;
40 import org.onap.policy.common.parameters.ValidationStatus;
41 import org.onap.policy.common.utils.validation.ParameterValidationUtils;
42 import org.onap.policy.models.base.Validated;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
48 * Apex plugin parameters for REST as an event carrier technology with Apex.
50 * <p>The parameters for this plugin are:
52 * <li>url: The URL that the Apex Rest client will connect to over REST for event reception or event sending. This
53 * parameter is mandatory.
54 * <li>httpMethod: The HTTP method to use when sending events over REST, legal values are POST (default) and PUT. When
55 * receiving events, the REST client plugin always uses the HTTP GET method.
56 * <li>httpHeaders, the HTTP headers to send on REST requests, optional parameter, defaults to none.
57 * <li>httpCodeFilter: a regular expression filter for returned HTTP codes, if the returned HTTP code passes this
58 * filter, then the request is assumed to have succeeded by the plugin, optional, defaults to allowing 2xx codes
59 * through, that is a regular expression of "[2][0-9][0-9]"
62 * @author Ning Xi(ning.xi@ericsson.com)
67 public class RestPluginCarrierTechnologyParameters extends CarrierTechnologyParameters {
68 // Get a reference to the logger
69 private static final Logger LOGGER = LoggerFactory.getLogger(RestPluginCarrierTechnologyParameters.class);
71 /** The supported HTTP methods. */
73 public enum HttpMethod {
81 /** The default HTTP code filter, allows 2xx HTTP codes through. */
82 public static final String DEFAULT_HTTP_CODE_FILTER = "[2][0-9][0-9]";
84 // Commonly occurring strings
85 private static final String HTTP_HEADERS = "httpHeaders";
86 private static final String HTTP_CODE_FILTER = "httpCodeFilter";
88 // Regular expression patterns for finding and checking keys in URLs
89 private static final Pattern patternProperKey = Pattern.compile("(?<=\\{)[^}]*(?=\\})");
90 protected static final Pattern patternErrorKey = Pattern
91 .compile("(\\{[^\\{}]*.?\\{)|(\\{[^\\{}]*$)|(\\}[^\\{}]*.?\\})|(^[^\\{}]*.?\\})|\\{\\s*\\}");
94 protected String url = null;
95 protected HttpMethod httpMethod = null;
96 protected String[][] httpHeaders = null;
97 protected String httpCodeFilter = DEFAULT_HTTP_CODE_FILTER;
100 * Constructor to create a REST carrier technology parameters instance and
101 * register the instance with the parameter service.
103 public RestPluginCarrierTechnologyParameters() {
108 * Check if http headers have been set for the REST request.
110 * @return true if headers have been set
112 public boolean checkHttpHeadersSet() {
113 return httpHeaders != null && httpHeaders.length > 0;
117 * Gets the http headers for the REST request as a multivalued map.
119 * @return the headers
121 public MultivaluedMap<String, Object> getHttpHeadersAsMultivaluedMap() {
122 if (httpHeaders == null) {
126 // Load the HTTP headers into the map
127 MultivaluedMap<String, Object> httpHeaderMap = new MultivaluedHashMap<>();
129 for (String[] httpHeader : httpHeaders) {
130 httpHeaderMap.putSingle(httpHeader[0], httpHeader[1]);
133 return httpHeaderMap;
137 * Sets the header for the REST request.
139 * @param httpHeaders the incoming HTTP headers
141 public void setHttpHeaders(final String[][] httpHeaders) {
142 this.httpHeaders = httpHeaders;
146 * Get the tag for the REST Producer Properties.
148 * @return set of the tags
150 public Set<String> getKeysFromUrl() {
151 Matcher matcher = patternProperKey.matcher(getUrl());
152 Set<String> key = new HashSet<>();
153 while (matcher.find()) {
154 key.add(matcher.group());
163 public BeanValidationResult validate() {
164 BeanValidationResult result = super.validate();
166 result.addResult(validateUrl());
167 result.addResult(validateHttpHeaders());
168 result.addResult(validateHttpCodeFilter());
178 * <br/>http://www.blah.com/{par1/somethingelse (Missing end tag) use {[^\\{}]*$
179 * <br/>http://www.blah.com/{par1/{some}thingelse (Nested tag) use {[^}]*{
180 * <br/>http://www.blah.com/{par1}/some}thingelse (Missing start tag1) use }[^{}]*.}
181 * <br/>http://www.blah.com/par1}/somethingelse (Missing start tag2) use }[^{}]*}
182 * <br/>http://www.blah.com/{}/somethingelse (Empty tag) use {[\s]*}
185 public ValidationResult validateUrl() {
186 // The URL may be optional so existence must be checked in the plugin code
187 String url2 = getUrl();
192 Matcher matcher = patternErrorKey.matcher(url2);
193 if (matcher.find()) {
194 final String urlInvalidMessage = "invalid URL has been set for event sending on " + getLabel();
195 return new ObjectValidationResult("url", url2, ValidationStatus.INVALID, urlInvalidMessage);
202 * Validate the HTTP headers.
204 * @return the result of the validation
206 private ValidationResult validateHttpHeaders() {
207 if (httpHeaders == null) {
211 BeanValidationResult result = new BeanValidationResult(HTTP_HEADERS, httpHeaders);
214 for (String[] httpHeader : httpHeaders) {
215 final String label = "entry " + (item++);
216 final List<String> value = (httpHeader == null ? null : Arrays.asList(httpHeader));
217 BeanValidationResult result2 = new BeanValidationResult(label, value);
219 if (httpHeader == null) {
220 // note: add to result, not result2
221 result.addResult(label, null, ValidationStatus.INVALID, Validated.IS_NULL);
223 } else if (httpHeader.length != 2) {
224 // note: add to result, not result2
225 result.addResult(label, value, ValidationStatus.INVALID, "must have one key and one value");
227 } else if (!ParameterValidationUtils.validateStringParameter(httpHeader[0])) {
228 result2.addResult("key", httpHeader[0], ValidationStatus.INVALID, Validated.IS_BLANK);
230 } else if (!ParameterValidationUtils.validateStringParameter(httpHeader[1])) {
231 result2.addResult("value", httpHeader[1], ValidationStatus.INVALID, Validated.IS_BLANK);
234 result.addResult(result2);
241 * Validate the HTTP code filter.
243 public ValidationResult validateHttpCodeFilter() {
244 if (httpCodeFilter == null) {
245 httpCodeFilter = DEFAULT_HTTP_CODE_FILTER;
247 } else if (StringUtils.isBlank(httpCodeFilter)) {
248 return new ObjectValidationResult(HTTP_CODE_FILTER, httpCodeFilter, ValidationStatus.INVALID,
249 "must be a three digit regular expression");
252 Pattern.compile(httpCodeFilter);
253 } catch (PatternSyntaxException pse) {
254 LOGGER.debug("Invalid HTTP code filter", pse);
255 String message = "Invalid HTTP code filter, the filter must be specified as a three digit "
256 + "regular expression: " + pse.getMessage();
257 return new ObjectValidationResult(HTTP_CODE_FILTER, httpCodeFilter, ValidationStatus.INVALID,
269 public String toString() {
270 return getLabel() + "CarrierTechnologyParameters [url=" + url + ", httpMethod=" + httpMethod + ", httpHeaders="
271 + Arrays.deepToString(httpHeaders) + ", httpCodeFilter=" + httpCodeFilter + "]";