diff options
author | Bansal, Nitin (nb121v) <nitin.bansal@amdocs.com> | 2017-05-08 17:20:38 -0400 |
---|---|---|
committer | Bansal, Nitin (nb121v) <nitin.bansal@amdocs.com> | 2017-05-09 09:58:26 -0400 |
commit | 3e372947d497014b4aad4c2c1d04d6c50a74e2e0 (patch) | |
tree | 8f5d2ac85f9e1f92b26f0b7f94cd6c3ae69f8d67 /src/main/java/org/openecomp/rest | |
parent | 42fcf3b1aff3efea329b61f1d5cc561d9a2490ae (diff) |
Initial OpenECOMP Data Router Core commit
Change-Id: Iee15b2f7870476eb48e4fb95f2564d3377749c6b
Signed-off-by: Bansal, Nitin (nb121v) <nitin.bansal@amdocs.com>
Diffstat (limited to 'src/main/java/org/openecomp/rest')
4 files changed, 479 insertions, 0 deletions
diff --git a/src/main/java/org/openecomp/rest/RestClientComponent.java b/src/main/java/org/openecomp/rest/RestClientComponent.java new file mode 100644 index 0000000..8d29af1 --- /dev/null +++ b/src/main/java/org/openecomp/rest/RestClientComponent.java @@ -0,0 +1,55 @@ +/** + * ============LICENSE_START======================================================= + * DataRouter + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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 ati + * + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.rest; + +import org.apache.camel.CamelContext; +import org.apache.camel.Endpoint; +import org.apache.camel.impl.UriEndpointComponent; + +import java.util.Map; + + +/** + * Represents the component that manages {@link RestClientEndpoint}. + */ +public class RestClientComponent extends UriEndpointComponent { + + public RestClientComponent() { + super(RestClientEndpoint.class); + } + + public RestClientComponent(CamelContext context) { + super(context, RestClientEndpoint.class); + } + + @Override + protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) + throws Exception { + + Endpoint endpoint = new RestClientEndpoint(uri, this); + setProperties(endpoint, parameters); + return endpoint; + } +} diff --git a/src/main/java/org/openecomp/rest/RestClientConsumer.java b/src/main/java/org/openecomp/rest/RestClientConsumer.java new file mode 100644 index 0000000..c9724f0 --- /dev/null +++ b/src/main/java/org/openecomp/rest/RestClientConsumer.java @@ -0,0 +1,41 @@ +/** + * ============LICENSE_START======================================================= + * DataRouter + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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 ati + * + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.rest; + +import org.apache.camel.Processor; +import org.apache.camel.impl.DefaultConsumer; + + +/** + * The RestClient consumer. + */ +public class RestClientConsumer extends DefaultConsumer { + private final RestClientEndpoint endpoint; + + public RestClientConsumer(RestClientEndpoint endpoint, Processor processor) { + super(endpoint, processor); + this.endpoint = endpoint; + } +} diff --git a/src/main/java/org/openecomp/rest/RestClientEndpoint.java b/src/main/java/org/openecomp/rest/RestClientEndpoint.java new file mode 100644 index 0000000..1b59704 --- /dev/null +++ b/src/main/java/org/openecomp/rest/RestClientEndpoint.java @@ -0,0 +1,127 @@ +/** + * ============LICENSE_START======================================================= + * DataRouter + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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 ati + * + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.rest; + +import org.apache.camel.Consumer; +import org.apache.camel.Processor; +import org.apache.camel.Producer; +import org.apache.camel.impl.DefaultEndpoint; +import org.apache.camel.spi.Metadata; +import org.apache.camel.spi.UriEndpoint; +import org.apache.camel.spi.UriParam; +import org.apache.camel.spi.UriPath; + +import java.util.Map; + + +/** + * Represents a RestClient endpoint. + */ +@UriEndpoint(scheme = "ecomp-rest", syntax = "ecomp-rest:op", + consumerClass = RestClientConsumer.class, label = "RestClient2", title = "") +public class RestClientEndpoint extends DefaultEndpoint { + + public static final String CONTEXT_PARAM_CLIENT_CERT = "ecomp-client-cert"; + public static final String CONTEXT_PARAM_KEYSTORE = "ecomp-keystore"; + public static final String CONTEXT_PARAM_KEYSTORE_PWD = "ecomp-keystore-password"; + + public static final String IN_HEADER_URL = "ecomp-url"; + + public static final String OUT_HEADER_RESPONSE_CODE = "ecomp-response-code"; + public static final String OUT_HEADER_RESPONSE_MSG = "ecomp-response-message"; + + @UriPath + @Metadata(required = "true") + private String op; + + @UriParam + private String ecompClientCert; + + @UriParam + private String ecompKeystore; + + @UriParam + private String ecompKeystorePassword; + + + public RestClientEndpoint() {} + + public RestClientEndpoint(String uri, RestClientComponent component) { + super(uri, component); + } + + public RestClientEndpoint(String endpointUri) { + super(endpointUri); + } + + @Override + protected void setProperties(Object bean, Map<String, Object> parameters) throws Exception { + super.setProperties(bean, parameters); + } + + public Producer createProducer() throws Exception { + return new RestClientProducer(this); + } + + public Consumer createConsumer(Processor processor) throws Exception { + return new RestClientConsumer(this, processor); + } + + public boolean isSingleton() { + return true; + } + + public String getOp() { + return op; + } + + public void setOp(String op) { + this.op = op; + } + + public String getEcompClientCert() { + return ecompClientCert; + } + + public void setEcompClientCert(String ecompClientCert) { + this.ecompClientCert = ecompClientCert; + } + + public String getEcompKeystore() { + return ecompKeystore; + } + + public void setEcompKeystore(String ecompKeystore) { + this.ecompKeystore = ecompKeystore; + } + + public String getEcompKeystorePassword() { + return ecompKeystorePassword; + } + + public void setEcompKeystorePassword(String ecompKeystorePassword) { + this.ecompKeystorePassword = ecompKeystorePassword; + } +} diff --git a/src/main/java/org/openecomp/rest/RestClientProducer.java b/src/main/java/org/openecomp/rest/RestClientProducer.java new file mode 100644 index 0000000..3a8df18 --- /dev/null +++ b/src/main/java/org/openecomp/rest/RestClientProducer.java @@ -0,0 +1,256 @@ +/** + * ============LICENSE_START======================================================= + * DataRouter + * ================================================================================ + * Copyright © 2017 AT&T Intellectual Property. + * Copyright © 2017 Amdocs + * All rights reserved. + * ================================================================================ + * 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 ati + * + * 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. + * ============LICENSE_END========================================================= + * + * ECOMP and OpenECOMP are trademarks + * and service marks of AT&T Intellectual Property. + */ +package org.openecomp.rest; + +import org.apache.camel.Exchange; +import org.apache.camel.impl.DefaultProducer; +import org.eclipse.jetty.util.security.Password; +import org.openecomp.cl.api.Logger; +import org.openecomp.cl.eelf.LoggerFactory; +import org.openecomp.event.EventBusConsumer; + +import org.openecomp.restclient.client.Headers; +import org.openecomp.restclient.client.OperationResult; +import org.openecomp.restclient.client.RestClient; +import org.openecomp.restclient.rest.HttpUtil; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + + +/** + * The EcompRest producer. + */ +public class RestClientProducer extends DefaultProducer { + + private static enum Operation { + GET, PUT, POST, DELETE + } + + private RestClientEndpoint endpoint; + + /** REST client used for sending HTTP requests. */ + private RestClient restClient; + + private Logger logger = LoggerFactory.getInstance().getLogger(RestClientProducer.class); + + + public RestClientProducer(RestClientEndpoint endpoint) { + super(endpoint); + this.endpoint = endpoint; + } + + @Override + public void process(Exchange exchange) { + + // Extract the URL for our REST request from the IN message header. + String url = exchange.getIn().getHeader(RestClientEndpoint.IN_HEADER_URL).toString(); + + // Populate the HTTP Request header values from any values passed in via the + // IN message headers. + Map<String, List<String>> headers = populateRestHeaders(exchange); + + if (logger.isDebugEnabled()) { + StringBuilder sb = new StringBuilder(); + sb.append("Process REST request - operation=").append(getOperation(exchange)); + sb.append(" headers=["); + for (String key : headers.keySet()) { + sb.append("{").append(key).append("->").append(headers.get(key)).append("} "); + } + sb.append("]"); + sb.append(" content: ").append(exchange.getIn().getBody()); + logger.debug(sb.toString()); + } + + // Now, invoke the REST client to perform the operation. + OperationResult result = null; + switch (getOperation(exchange)) { + + case GET: + result = getRestClient().get(url, headers, MediaType.APPLICATION_JSON_TYPE); + break; + + case PUT: + result = getRestClient().put(url, exchange.getIn().getBody().toString(), headers, + MediaType.APPLICATION_JSON_TYPE, null); + break; + + case POST: + result = getRestClient().post(url, exchange.getIn().getBody().toString(), headers, + MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE); + break; + + case DELETE: + result = getRestClient().delete(url, headers, MediaType.APPLICATION_JSON_TYPE); + break; + + default: + // The supplied operation is not supported. + result = new OperationResult(); + result.setResultCode(Response.Status.BAD_REQUEST.getStatusCode()); + result.setFailureCause("Unsupported HTTP Operation: " + getOperation(exchange)); + + break; + } + + // Populate the OUT message with our result. + exchange.getOut().setHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_CODE, + result.getResultCode()); + if (HttpUtil.isHttpResponseClassSuccess(result.getResultCode())) { + exchange.getOut().setHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_MSG, + responseStatusStringFromResult(result)); + exchange.getOut().setBody(result.getResult()); + } else { + exchange.getOut().setHeader(RestClientEndpoint.OUT_HEADER_RESPONSE_MSG, + result.getFailureCause()); + } + + } + + + /** + * Extracts the requested REST operation from the exchange message. + * + * @param exchange - The Camel exchange to pull the operation from. + * + * @return - The REST operation being requested. + */ + private Operation getOperation(Exchange exchange) { + + String toEndpoint = ((String) exchange.getProperty(Exchange.TO_ENDPOINT)); + + String operation = toEndpoint.substring((toEndpoint.lastIndexOf("://") + 3)); + + int position = operation.indexOf('?'); + if (position >= 0) { + operation = operation.substring(0, position); + } + + return Operation.valueOf(operation.toUpperCase()); + } + + + + /** + * This method extracts values from the IN message which are intended to be used to populate the + * HTTP Header entries for our REST request. + * + * @param exchange - The Camel exchange to extract the HTTP header parameters from. + * + * @return - A map of HTTP header names and values. + */ + private Map<String, List<String>> populateRestHeaders(Exchange exchange) { + + Map<String, List<String>> headers = new HashMap<>(); + + if (exchange.getIn().getHeader(Headers.FROM_APP_ID) != null) { + headers.put(Headers.FROM_APP_ID, + Arrays.asList(exchange.getIn().getHeader(Headers.FROM_APP_ID).toString())); + } + if (exchange.getIn().getHeader(Headers.TRANSACTION_ID) != null) { + headers.put(Headers.TRANSACTION_ID, + Arrays.asList(exchange.getIn().getHeader(Headers.TRANSACTION_ID).toString())); + } + if (exchange.getIn().getHeader(Headers.RESOURCE_VERSION) != null) { + headers.put(Headers.RESOURCE_VERSION, + Arrays.asList(exchange.getIn().getHeader(Headers.RESOURCE_VERSION).toString())); + } + if (exchange.getIn().getHeader(Headers.ETAG) != null) { + headers.put(Headers.ETAG, Arrays.asList(exchange.getIn().getHeader(Headers.ETAG).toString())); + } + if (exchange.getIn().getHeader(Headers.IF_MATCH) != null) { + headers.put(Headers.IF_MATCH, + Arrays.asList(exchange.getIn().getHeader(Headers.IF_MATCH).toString())); + } + if (exchange.getIn().getHeader(Headers.IF_NONE_MATCH) != null) { + headers.put(Headers.IF_NONE_MATCH, + Arrays.asList(exchange.getIn().getHeader(Headers.IF_NONE_MATCH).toString())); + } + if (exchange.getIn().getHeader(Headers.ACCEPT) != null) { + headers.put(Headers.ACCEPT, + Arrays.asList(exchange.getIn().getHeader(Headers.ACCEPT).toString())); + } + if (exchange.getIn().getHeader("Content-Type") != null) { + headers.put("Content-Type", + Arrays.asList(exchange.getIn().getHeader("Content-Type").toString())); + } + + return headers; + } + + + /** + * This helper method converts an HTTP response code into the associated string. + * + * @param result - A result object to get the response code from. + * + * @return - The string message associated with the supplied response code. + */ + private String responseStatusStringFromResult(OperationResult result) { + + // Not every valid response code is actually represented by the Response.Status + // object, so we need to guard against missing codes, otherwise we throw null + // pointer exceptions when we try to generate our metrics logs... + Response.Status responseStatus = Response.Status.fromStatusCode(result.getResultCode()); + String responseStatusCodeString = ""; + if (responseStatus != null) { + responseStatusCodeString = responseStatus.toString(); + } + + return responseStatusCodeString; + } + + /** + * Instantiate the REST client that will be used for sending our HTTP requests. + * + * @return - An instance of the REST client. + */ + private RestClient getRestClient() { + + if (restClient == null) { + + String keystoreFilename = endpoint.getEcompKeystore(); + String keystorePassword = endpoint.getEcompKeystorePassword(); + String clientCertFilename = endpoint.getEcompClientCert(); + + if (logger.isDebugEnabled()) { + logger.debug("Instantiating REST Client with client_cert=" + clientCertFilename + + " keystore=" + keystoreFilename + " keystorePassword=" + keystorePassword); + } + + // Create REST client for search service + restClient = new RestClient().validateServerHostname(false).validateServerCertChain(true) + .clientCertFile(clientCertFilename) + .clientCertPassword(Password.deobfuscate(keystorePassword)).trustStore(keystoreFilename); + } + + return restClient; + } +} |