2 * ============LICENSE_START=======================================================
4 * ================================================================================
5 * Copyright © 2017-2018 AT&T Intellectual Property. All rights reserved.
6 * Copyright © 2017-2018 Amdocs
7 * ================================================================================
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 * ============LICENSE_END=========================================================
21 package org.onap.aai.datarouter.query;
23 import java.security.InvalidParameterException;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
27 import javax.ws.rs.BadRequestException;
29 import org.apache.camel.Exchange;
30 import org.apache.camel.RuntimeCamelException;
31 import org.onap.aai.rest.RestClientEndpoint;
32 import org.onap.aai.cl.api.Logger;
33 import org.onap.aai.cl.eelf.LoggerFactory;
35 public class ChameleonRouter extends QueryRouter {
37 Logger logger = LoggerFactory.getInstance().getLogger(ChameleonRouter.class.getName());
39 private String chameleonBaseURL;
41 private enum ChameleonAction {
42 GET_OBJECT_BY_ID, GET_REL_BY_ID, GET_OBJECT_RELS, GET_OBJECTS_BY_FILTER, GET_RELS_BY_FILTER
45 private static final Pattern QUERY_OBJECT_FILTER_URL_MATCH = Pattern.compile("/objects/filter(.*)");
46 private static final Pattern QUERY_REL_FILTER_URL_MATCH = Pattern.compile("/relationships/filter(.*)");
47 private static final Pattern QUERY_OBJECT_REL_URL_MATCH = Pattern.compile("/objects/relationships/(.*)");
48 private static final Pattern QUERY_OBJECT_ID_URL_MATCH = Pattern.compile("/objects/(.*)");
49 private static final Pattern QUERY_REL_ID_URL_MATCH = Pattern.compile("/relationships/(.*)");
51 private static final String ECOMP_QUERY_ID = "ECOMP_QUERY_ID";
52 private static final String ECOMP_QUERY_TYPE = "ECOMP_QUERY_TYPE";
54 public ChameleonRouter(String chameleonBaseURL) {
55 String baseURL = chameleonBaseURL.endsWith("/") ? chameleonBaseURL.substring(0, chameleonBaseURL.length() - 1)
57 if (checkRecursion(baseURL)) {
58 logger.error(QueryMsgs.QUERY_ERROR,
59 "Invalid chameleonBaseURL : Can't re-route back to DataRouter " + chameleonBaseURL);
60 throw new InvalidParameterException(
61 "Invalid chameleonBaseURL : Can't re-route back to DataRouter " + chameleonBaseURL);
63 this.chameleonBaseURL = baseURL;
66 public void setQueryRequest(Exchange exchange) {
68 ChameleonAction action = resolveChameleonAction(exchange);
69 String ecompUrl = buildUrl(exchange, action);
70 logger.info(QueryMsgs.QUERY_INFO, "Routing request to Chameleon service URL: " + ecompUrl);
71 exchange.getIn().setHeader(RestClientEndpoint.IN_HEADER_URL, ecompUrl);
72 exchange.getIn().setHeader("X-FromAppId", SERVICE_NAME);
73 exchange.getIn().setHeader("X-TransactionId", getTxId(exchange));
77 private boolean urlMatcher(Pattern p, String url) {
78 Matcher m = p.matcher(url);
79 if (m.matches() && !m.group(1).contains("/")) {
86 private ChameleonAction resolveChameleonAction(Exchange exchange) {
87 String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
88 path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
89 ChameleonAction action;
91 if (urlMatcher(QUERY_OBJECT_FILTER_URL_MATCH, path)) {
92 action = ChameleonAction.GET_OBJECTS_BY_FILTER;
93 } else if (urlMatcher(QUERY_REL_FILTER_URL_MATCH, path)) {
94 action = ChameleonAction.GET_RELS_BY_FILTER;
95 } else if (urlMatcher(QUERY_OBJECT_REL_URL_MATCH, path)) {
96 action = ChameleonAction.GET_OBJECT_RELS;
97 } else if (urlMatcher(QUERY_OBJECT_ID_URL_MATCH, path)) {
98 action = ChameleonAction.GET_OBJECT_BY_ID;
99 } else if (urlMatcher(QUERY_REL_ID_URL_MATCH, path)) {
100 action = ChameleonAction.GET_REL_BY_ID;
102 exchange.getIn().setHeader(ChameleonErrorProcessor.ECOMP_QUERY_ERROR_CODE, 404);
103 throw new RuntimeCamelException();
108 private String buildUrl(Exchange exchange, ChameleonAction action) {
109 String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
110 path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
111 String queryParams = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
112 String ecompUrl = "";
116 case GET_OBJECT_BY_ID:
117 ID = path.substring(path.lastIndexOf("/") + 1, path.length());
118 if (ID == null || ID.isEmpty()) {
119 throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
121 if (queryParams != null && !queryParams.isEmpty()) {
122 ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
125 ecompUrl = chameleonBaseURL + "/" + ID;
128 exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
129 exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_BY_ID);
133 ID = path.substring(path.lastIndexOf("/") + 1, path.length());
134 if (ID == null || ID.isEmpty()) {
135 throw new IllegalArgumentException("Invalid URI path with no Relationship ID: " + path);
137 if (queryParams != null && !queryParams.isEmpty()) {
138 ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
141 ecompUrl = chameleonBaseURL + "/" + ID;
144 exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
145 exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_REL_BY_ID);
148 case GET_OBJECT_RELS:
149 ID = path.substring(path.lastIndexOf("/") + 1, path.length());
150 if (ID == null || ID.isEmpty()) {
151 throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
153 if (queryParams != null && !queryParams.isEmpty()) {
154 // TODO: Fix the URL for getting object relations when Chameloen
156 ecompUrl = chameleonBaseURL + "/relations" + ID + "?" + queryParams;
159 ecompUrl = chameleonBaseURL + "/relations" + ID;
162 exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
163 exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_RELS);
166 case GET_OBJECTS_BY_FILTER:
167 if (queryParams != null && !queryParams.isEmpty()) {
168 // TODO: Fix the URL for getting object filter when Chameloen
170 ecompUrl = chameleonBaseURL + "/filter?" + queryParams;
172 ecompUrl = chameleonBaseURL + "/filter";
174 exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECTS_BY_FILTER);
177 case GET_RELS_BY_FILTER:
178 if (queryParams != null && !queryParams.isEmpty()) {
179 // TODO: Fix the URL for getting rel filter when Chameloen
181 ecompUrl = chameleonBaseURL + "/filter?" + queryParams;
183 ecompUrl = chameleonBaseURL + "/filter";
185 exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_RELS_BY_FILTER);
193 public void setQueryResponse(Exchange exchange) {
194 parseResponse(exchange);
195 adjustHeaders(exchange);
198 private void adjustHeaders(Exchange exchange) {
199 // Remove the internal heders
200 exchange.getIn().removeHeader(ECOMP_QUERY_ID);
201 exchange.getIn().removeHeader(ECOMP_QUERY_TYPE);
204 private void parseResponse(Exchange exchange) throws BadRequestException {
206 ChameleonAction action = exchange.getIn().getHeader(ECOMP_QUERY_TYPE, ChameleonAction.class);
207 Integer httpResponseCode = exchange.getIn().getHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_CODE, Integer.class);
211 case GET_OBJECT_BY_ID:
212 if (httpResponseCode >= 200 && httpResponseCode <= 299) {
213 ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
214 if (ID == null || ID.isEmpty()) {
215 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
217 ChameleonResponseBuiler.buildEntity(exchange, ID);
220 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
224 if (httpResponseCode >= 200 && httpResponseCode <= 299) {
225 ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
226 if (ID == null || ID.isEmpty()) {
227 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
229 ChameleonResponseBuiler.buildEntity(exchange, ID);
232 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
235 case GET_OBJECT_RELS:
236 if (httpResponseCode >= 200 && httpResponseCode <= 299) {
237 ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
238 if (ID == null || ID.isEmpty()) {
239 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
241 ChameleonResponseBuiler.buildObjectRelationship(exchange, ID);
244 // TODO:Return 200 with empty body for now until chameleon supports this
246 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
247 exchange.getIn().setBody("[]");
250 case GET_OBJECTS_BY_FILTER:
251 if (httpResponseCode >= 200 && httpResponseCode <= 299) {
252 ChameleonResponseBuiler.buildCollection(exchange);
254 // TODO:Return 200 with empty body for now until chameleon supports this
256 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
257 exchange.getIn().setBody("[]");
260 case GET_RELS_BY_FILTER:
261 if (httpResponseCode >= 200 && httpResponseCode <= 299) {
262 ChameleonResponseBuiler.buildCollection(exchange);
264 // TODO:Return 200 with empty body for now until chameleon supports this
266 exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
267 exchange.getIn().setBody("[]");