* limitations under the License.
* ============LICENSE_END=========================================================
*/
-package org.onap.aai.datarouter.query;
+package org.onap.aai.datarouter.query;
import java.security.InvalidParameterException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.annotation.PostConstruct;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response.Status;
+import javax.ws.rs.BadRequestException;
-import org.eclipse.jetty.util.security.Password;
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
+import org.onap.aai.rest.RestClientEndpoint;
import org.onap.aai.cl.api.Logger;
import org.onap.aai.cl.eelf.LoggerFactory;
-import org.onap.aai.datarouter.exception.DataRouterException;
-import org.onap.aai.datarouter.util.DataRouterConstants;
-import org.onap.aai.restclient.client.OperationResult;
-import org.onap.aai.restclient.client.RestClient;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-@Component
-@Qualifier("chameleon")
-public class ChameleonRouter implements QueryRouter {
+public class ChameleonRouter extends QueryRouter {
Logger logger = LoggerFactory.getInstance().getLogger(ChameleonRouter.class.getName());
private String chameleonBaseURL;
- private RestClient restClient ;
-
private enum ChameleonAction {
GET_OBJECT_BY_ID, GET_REL_BY_ID, GET_OBJECT_RELS, GET_OBJECTS_BY_FILTER, GET_RELS_BY_FILTER
};
private static final Pattern QUERY_OBJECT_ID_URL_MATCH = Pattern.compile("/objects/(.*)");
private static final Pattern QUERY_REL_ID_URL_MATCH = Pattern.compile("/relationships/(.*)");
+ private static final String ECOMP_QUERY_ID = "ECOMP_QUERY_ID";
+ private static final String ECOMP_QUERY_TYPE = "ECOMP_QUERY_TYPE";
- public ChameleonRouter(){}
-
-
- public ChameleonRouter(String chameleonBaseURL, RestClientConfig config) {
- this.chameleonBaseURL = chameleonBaseURL;
- this.restClient = new RestClient().validateServerHostname(false).validateServerCertChain(true)
- .clientCertFile(config.getCertPath())
- .clientCertPassword(Password.deobfuscate(config.getCertPassword()))
- .trustStore(config.getTrustStorePath())
- .connectTimeoutMs(config.getConnectionTimeout())
- .readTimeoutMs(config.getReadTimeout());
- validate();
- }
-
-
- public void validate() {
+ public ChameleonRouter(String chameleonBaseURL) {
String baseURL = chameleonBaseURL.endsWith("/") ? chameleonBaseURL.substring(0, chameleonBaseURL.length() - 1)
: chameleonBaseURL;
- if (baseURL.contains(DATA_ROUTER_PORT)) {
+ if (checkRecursion(baseURL)) {
logger.error(QueryMsgs.QUERY_ERROR,
"Invalid chameleonBaseURL : Can't re-route back to DataRouter " + chameleonBaseURL);
throw new InvalidParameterException(
this.chameleonBaseURL = baseURL;
}
+ public void setQueryRequest(Exchange exchange) {
+ setMDC(exchange);
+ ChameleonAction action = resolveChameleonAction(exchange);
+ String ecompUrl = buildUrl(exchange, action);
+ logger.info(QueryMsgs.QUERY_INFO, "Routing request to Chameleon service URL: " + ecompUrl);
+ exchange.getIn().setHeader(RestClientEndpoint.IN_HEADER_URL, ecompUrl);
+ exchange.getIn().setHeader("X-FromAppId", SERVICE_NAME);
+ exchange.getIn().setHeader("X-TransactionId", getTxId(exchange));
+
+ }
+
private boolean urlMatcher(Pattern p, String url) {
Matcher m = p.matcher(url);
if (m.matches() && !m.group(1).contains("/")) {
}
}
- private ChameleonAction resolveChameleonAction(String urlContext) throws DataRouterException {
-
- urlContext = urlContext.endsWith("/") ? urlContext.substring(0, urlContext.length() - 1) : urlContext;
+ private ChameleonAction resolveChameleonAction(Exchange exchange) {
+ String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
+ path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
ChameleonAction action;
- if (urlMatcher(QUERY_OBJECT_FILTER_URL_MATCH, urlContext)) {
+ if (urlMatcher(QUERY_OBJECT_FILTER_URL_MATCH, path)) {
action = ChameleonAction.GET_OBJECTS_BY_FILTER;
- } else if (urlMatcher(QUERY_REL_FILTER_URL_MATCH, urlContext)) {
+ } else if (urlMatcher(QUERY_REL_FILTER_URL_MATCH, path)) {
action = ChameleonAction.GET_RELS_BY_FILTER;
- } else if (urlMatcher(QUERY_OBJECT_REL_URL_MATCH, urlContext)) {
+ } else if (urlMatcher(QUERY_OBJECT_REL_URL_MATCH, path)) {
action = ChameleonAction.GET_OBJECT_RELS;
- } else if (urlMatcher(QUERY_OBJECT_ID_URL_MATCH, urlContext)) {
+ } else if (urlMatcher(QUERY_OBJECT_ID_URL_MATCH, path)) {
action = ChameleonAction.GET_OBJECT_BY_ID;
- } else if (urlMatcher(QUERY_REL_ID_URL_MATCH, urlContext)) {
+ } else if (urlMatcher(QUERY_REL_ID_URL_MATCH, path)) {
action = ChameleonAction.GET_REL_BY_ID;
} else {
-
- throw new DataRouterException("", Status.NOT_FOUND);
+ exchange.getIn().setHeader(ChameleonErrorProcessor.ECOMP_QUERY_ERROR_CODE, 404);
+ throw new RuntimeCamelException();
}
return action;
}
- private String buildUrl(String urlContext, String queryParams, ChameleonAction action) {
-
- urlContext = urlContext.endsWith("/") ? urlContext.substring(0, urlContext.length() - 1) : urlContext;
+ private String buildUrl(Exchange exchange, ChameleonAction action) {
+ String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class);
+ path = path.endsWith("/") ? path.substring(0, path.length() - 1) : path;
+ String queryParams = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
String ecompUrl = "";
String ID = "";
switch (action) {
case GET_OBJECT_BY_ID:
- ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
+ ID = path.substring(path.lastIndexOf("/") + 1, path.length());
if (ID == null || ID.isEmpty()) {
- throw new IllegalArgumentException("Invalid URI path with no Object ID: " + urlContext);
+ throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
} else {
if (queryParams != null && !queryParams.isEmpty()) {
ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
ecompUrl = chameleonBaseURL + "/" + ID;
}
}
-
+ exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
+ exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_BY_ID);
break;
case GET_REL_BY_ID:
- ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
+ ID = path.substring(path.lastIndexOf("/") + 1, path.length());
if (ID == null || ID.isEmpty()) {
- throw new IllegalArgumentException("Invalid URI path with no Relationship ID: " + urlContext);
+ throw new IllegalArgumentException("Invalid URI path with no Relationship ID: " + path);
} else {
if (queryParams != null && !queryParams.isEmpty()) {
ecompUrl = chameleonBaseURL + "/" + ID + "?" + queryParams;
ecompUrl = chameleonBaseURL + "/" + ID;
}
}
-
+ exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
+ exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_REL_BY_ID);
break;
case GET_OBJECT_RELS:
- ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
+ ID = path.substring(path.lastIndexOf("/") + 1, path.length());
if (ID == null || ID.isEmpty()) {
- throw new IllegalArgumentException("Invalid URI path with no Object ID: " + urlContext);
+ throw new IllegalArgumentException("Invalid URI path with no Object ID: " + path);
} else {
if (queryParams != null && !queryParams.isEmpty()) {
// TODO: Fix the URL for getting object relations when Chameloen
ecompUrl = chameleonBaseURL + "/relations" + ID;
}
}
-
+ exchange.getIn().setHeader(ECOMP_QUERY_ID, ID);
+ exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECT_RELS);
break;
case GET_OBJECTS_BY_FILTER:
} else {
ecompUrl = chameleonBaseURL + "/filter";
}
-
+ exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_OBJECTS_BY_FILTER);
break;
case GET_RELS_BY_FILTER:
} else {
ecompUrl = chameleonBaseURL + "/filter";
}
-
+ exchange.getIn().setHeader(ECOMP_QUERY_TYPE, ChameleonAction.GET_RELS_BY_FILTER);
break;
}
return ecompUrl;
}
- private String parseResponse(String urlContext, OperationResult result, ChameleonAction action)
- throws DataRouterException {
+ public void setQueryResponse(Exchange exchange) {
+ parseResponse(exchange);
+ adjustHeaders(exchange);
+ }
+
+ private void adjustHeaders(Exchange exchange) {
+ // Remove the internal heders
+ exchange.getIn().removeHeader(ECOMP_QUERY_ID);
+ exchange.getIn().removeHeader(ECOMP_QUERY_TYPE);
+ }
- Integer httpResponseCode = result.getResultCode();
- String ID = urlContext.substring(urlContext.lastIndexOf("/") + 1, urlContext.length());
+ private void parseResponse(Exchange exchange) throws BadRequestException {
+
+ ChameleonAction action = exchange.getIn().getHeader(ECOMP_QUERY_TYPE, ChameleonAction.class);
+ Integer httpResponseCode = exchange.getIn().getHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_CODE, Integer.class);
+ String ID = "";
switch (action) {
case GET_OBJECT_BY_ID:
if (httpResponseCode >= 200 && httpResponseCode <= 299) {
+ ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
if (ID == null || ID.isEmpty()) {
- throw new DataRouterException("", Status.BAD_REQUEST);
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
} else {
- return ChameleonResponseBuiler.buildEntity(result.getResult(), ID);
+ ChameleonResponseBuiler.buildEntity(exchange, ID);
}
} else {
- throw new DataRouterException("", Status.fromStatusCode(httpResponseCode));
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
}
-
+ break;
case GET_REL_BY_ID:
if (httpResponseCode >= 200 && httpResponseCode <= 299) {
-
+ ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
if (ID == null || ID.isEmpty()) {
- throw new DataRouterException("", Status.BAD_REQUEST);
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
} else {
- return ChameleonResponseBuiler.buildEntity(result.getResult(), ID);
+ ChameleonResponseBuiler.buildEntity(exchange, ID);
}
} else {
- throw new DataRouterException("", Status.fromStatusCode(httpResponseCode));
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, httpResponseCode);
}
-
+ break;
case GET_OBJECT_RELS:
-
- // TODO:Return 200 with empty body for now until chameleon supports this
- // query
- if (ID == null || ID.isEmpty()) {
- throw new DataRouterException("", Status.BAD_REQUEST);
+ if (httpResponseCode >= 200 && httpResponseCode <= 299) {
+ ID = exchange.getIn().getHeader(ECOMP_QUERY_ID, String.class);
+ if (ID == null || ID.isEmpty()) {
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 400);
+ } else {
+ ChameleonResponseBuiler.buildObjectRelationship(exchange, ID);
+ }
} else {
- return ChameleonResponseBuiler.buildObjectRelationship(result.getResult(), ID);
+ // TODO:Return 200 with empty body for now until chameleon supports this
+ // query
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
+ exchange.getIn().setBody("[]");
}
-
+ break;
case GET_OBJECTS_BY_FILTER:
- // TODO:Return 200 with empty body for now until chameleon supports this
- // query
- return ChameleonResponseBuiler.buildCollection(result.getResult());
-
+ if (httpResponseCode >= 200 && httpResponseCode <= 299) {
+ ChameleonResponseBuiler.buildCollection(exchange);
+ } else {
+ // TODO:Return 200 with empty body for now until chameleon supports this
+ // query
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
+ exchange.getIn().setBody("[]");
+ }
+ break;
case GET_RELS_BY_FILTER:
- // TODO:Return 200 with empty body for now until chameleon supports this
- // query
- return ChameleonResponseBuiler.buildCollection(result.getResult());
- default:
- throw new DataRouterException("", Status.NOT_FOUND);
-
- }
-
- }
+ if (httpResponseCode >= 200 && httpResponseCode <= 299) {
+ ChameleonResponseBuiler.buildCollection(exchange);
+ } else {
+ // TODO:Return 200 with empty body for now until chameleon supports this
+ // query
+ exchange.getIn().setHeader(Exchange.HTTP_RESPONSE_CODE, 200);
+ exchange.getIn().setBody("[]");
+ }
+ break;
- @Override
- public String process(String urlContext, String queryParams, Map<String, List<String>> headers)
- throws DataRouterException {
- String response;
- ChameleonAction action = resolveChameleonAction(urlContext);
- String chameleonURL = buildUrl(urlContext, queryParams, action);
- logger.info(QueryMsgs.QUERY_INFO, "Routing request to Chameleon service URL: " + chameleonURL);
-
- headers = headers == null ? new HashMap<String, List<String>>() : headers;
- headers.put("X-FromAppId", Arrays.asList(DataRouterConstants.DATA_ROUTER_SERVICE_NAME));
- OperationResult result = restClient.get(chameleonURL, headers, MediaType.APPLICATION_JSON_TYPE);
-
- try {
- response = parseResponse(urlContext, result, action);
- } catch (DataRouterException ex) {
- logger.info(QueryMsgs.QUERY_ERROR,
- "Error while calling Chameleon service URL: " + chameleonURL + " failure cause: " + result.getFailureCause());
- throw ex;
}
- return response;
}
}