You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2016/08/26 16:02:38 UTC
[10/23] camel git commit: CAMEL-10164: swagger component for making
rest calls with swagger schema validation and facade to actual HTTP client in
use
CAMEL-10164: swagger component for making rest calls with swagger schema validation and facade to actual HTTP client in use
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/69c12a0a
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/69c12a0a
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/69c12a0a
Branch: refs/heads/master
Commit: 69c12a0ab5d7c1f3152f0f2295ce1fa00f87170d
Parents: 2e39b2c
Author: Claus Ibsen <da...@apache.org>
Authored: Thu Aug 25 07:46:53 2016 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Fri Aug 26 16:53:31 2016 +0200
----------------------------------------------------------------------
.../apache/camel/spi/RestProducerFactory.java | 8 +-
.../component/jetty/JettyHttpComponent.java | 16 +-
.../swagger/component/SwaggerProducer.java | 169 +++++++++++--------
.../component/DummyRestProducerFactory.java | 20 ++-
4 files changed, 117 insertions(+), 96 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/69c12a0a/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
----------------------------------------------------------------------
diff --git a/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java b/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
index 255ea6a..ae7f6f5 100644
--- a/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
+++ b/camel-core/src/main/java/org/apache/camel/spi/RestProducerFactory.java
@@ -32,21 +32,17 @@ public interface RestProducerFactory {
* Creates a new REST producer.
*
* @param camelContext the camel context
- * @param exchange the exchange
* @param scheme scheme to use such as http or https
* @param host host (incl port) of the REST service
* @param verb HTTP verb such as GET, POST
* @param basePath base path
* @param uriTemplate uri template
- * @param resolvedUriTemplate uri template where path parameters has been resolved
- * @param queryParameters query parameters
* @param consumes media-types for what the REST service consume as input (accept-type), is <tt>null</tt> or <tt>*/*</tt> for anything
* @param produces media-types for what the REST service produces as output, can be <tt>null</tt>
* @param parameters additional parameters
* @return a newly created REST producer
* @throws Exception can be thrown
*/
- Producer createProducer(CamelContext camelContext, Exchange exchange, String scheme, String host,
- String verb, String basePath, String uriTemplate, String resolvedUriTemplate, String queryParameters,
- String consumes, String produces, Map<String, Object> parameters) throws Exception;
+ Producer createProducer(CamelContext camelContext, String scheme, String host,
+ String verb, String basePath, String uriTemplate, String consumes, String produces, Map<String, Object> parameters) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/camel/blob/69c12a0a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
----------------------------------------------------------------------
diff --git a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
index 6b9394f..3b3e91d 100644
--- a/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
+++ b/components/camel-jetty-common/src/main/java/org/apache/camel/component/jetty/JettyHttpComponent.java
@@ -1151,25 +1151,13 @@ public abstract class JettyHttpComponent extends HttpCommonComponent implements
}
@Override
- public Producer createProducer(CamelContext camelContext, Exchange exchange, String scheme, String host,
- String verb, String basePath, String uriTemplate, String resolvedUriTemplate, String queryParameters,
+ public Producer createProducer(CamelContext camelContext, String scheme, String host,
+ String verb, String basePath, String uriTemplate,
String consumes, String produces, Map<String, Object> parameters) throws Exception {
// avoid leading slash
basePath = FileUtil.stripLeadingSeparator(basePath);
uriTemplate = FileUtil.stripLeadingSeparator(uriTemplate);
- resolvedUriTemplate = FileUtil.stripLeadingSeparator(resolvedUriTemplate);
-
- // does the uri template use path parameters?
- if (uriTemplate.contains("{") && resolvedUriTemplate != null) {
- // if so us a header for the dynamic uri template so we reuse same endpoint but the header overrides the actual url to use
- String overrideUri = String.format("%s://%s/%s/%s", scheme, host, basePath, resolvedUriTemplate);
- exchange.getIn().setHeader(Exchange.HTTP_URI, overrideUri);
- }
- if (queryParameters != null) {
- // use a header for the query parameters
- exchange.getIn().setHeader(Exchange.HTTP_QUERY, queryParameters);
- }
// get the endpoint
String url = "jetty:%s://%s/%s/%s";
http://git-wip-us.apache.org/repos/asf/camel/blob/69c12a0a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java
index a5d0c18..7e1fda2 100644
--- a/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java
+++ b/components/camel-swagger-java/src/main/java/org/apache/camel/swagger/component/SwaggerProducer.java
@@ -37,7 +37,7 @@ import org.apache.camel.impl.DefaultAsyncProducer;
import org.apache.camel.spi.RestProducerFactory;
import org.apache.camel.util.AsyncProcessorConverterHelper;
import org.apache.camel.util.CollectionStringBuffer;
-import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.FileUtil;
import org.apache.camel.util.ServiceHelper;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.URISupport;
@@ -49,6 +49,8 @@ public class SwaggerProducer extends DefaultAsyncProducer {
private static final Logger LOG = LoggerFactory.getLogger(SwaggerProducer.class);
private Swagger swagger;
+ private Operation operation;
+ private AsyncProcessor producer;
public SwaggerProducer(Endpoint endpoint) {
super(endpoint);
@@ -61,29 +63,14 @@ public class SwaggerProducer extends DefaultAsyncProducer {
@Override
public boolean process(Exchange exchange, AsyncCallback callback) {
- String verb = getEndpoint().getVerb();
- String path = getEndpoint().getPath();
-
- Operation operation = getSwaggerOperation(verb, path);
- if (operation == null) {
- exchange.setException(new IllegalArgumentException("Swagger schema does not contain operation for " + verb + ":" + path));
- callback.done(true);
- return true;
- }
+ // TODO: bind to consumes context-type
+ // TODO: if binding is turned on/off/auto etc
try {
- // TODO: bind to consumes context-type
- // TODO: if binding is turned on/off/auto etc
- // TODO: build dynamic uri for component (toD, headers)
- // create http producer to use for calling the remote HTTP service
- // TODO: create the producer once and reuse (create HTTP_XXX headers for dynamic values)
- Producer producer = createHttpProducer(exchange, operation, verb, path);
if (producer != null) {
- ServiceHelper.startService(producer);
- AsyncProcessor async = AsyncProcessorConverterHelper.convert(producer);
- return async.process(exchange, callback);
+ prepareExchange(exchange);
+ return producer.process(exchange, callback);
}
-
} catch (Throwable e) {
exchange.setException(e);
}
@@ -93,6 +80,96 @@ public class SwaggerProducer extends DefaultAsyncProducer {
return true;
}
+ protected void prepareExchange(Exchange exchange) throws Exception {
+ boolean hasPath = false;
+ boolean hasQuery = false;
+
+ // uri template with path parameters resolved
+ String resolvedUriTemplate = getEndpoint().getPath();
+ // for query parameters
+ Map<String, Object> query = new LinkedHashMap<>();
+ for (Parameter param : operation.getParameters()) {
+ if ("query".equals(param.getIn())) {
+ String name = param.getName();
+ if (name != null) {
+ String value = exchange.getIn().getHeader(name, String.class);
+ if (value != null) {
+ hasQuery = true;
+ // we need to remove the header as they are sent as query instead
+ // TODO: we could use a header filter strategy to skip these headers
+ exchange.getIn().removeHeader(param.getName());
+ query.put(name, value);
+ } else if (param.getRequired()) {
+ throw new NoSuchHeaderException(exchange, name, String.class);
+ }
+ }
+ } else if ("path".equals(param.getIn())) {
+ String value = exchange.getIn().getHeader(param.getName(), String.class);
+ if (value != null) {
+ hasPath = true;
+ // we need to remove the header as they are sent as path instead
+ // TODO: we could use a header filter strategy to skip these headers
+ exchange.getIn().removeHeader(param.getName());
+ String token = "{" + param.getName() + "}";
+ resolvedUriTemplate = StringHelper.replaceAll(resolvedUriTemplate, token, value);
+ } else if (param.getRequired()) {
+ // the parameter is required but we do not have a header
+ throw new NoSuchHeaderException(exchange, param.getName(), String.class);
+ }
+ }
+ }
+
+ if (hasQuery) {
+ String queryParameters = URISupport.createQueryString(query);
+ exchange.getIn().setHeader(Exchange.HTTP_QUERY, queryParameters);
+ }
+
+ if (hasPath) {
+ String scheme = swagger.getSchemes() != null && swagger.getSchemes().size() == 1 ? swagger.getSchemes().get(0).toValue() : "http";
+ String host = getEndpoint().getHost() != null ? getEndpoint().getHost() : swagger.getHost();
+ String basePath = swagger.getBasePath();
+ basePath = FileUtil.stripLeadingSeparator(basePath);
+ resolvedUriTemplate = FileUtil.stripLeadingSeparator(resolvedUriTemplate);
+ // if so us a header for the dynamic uri template so we reuse same endpoint but the header overrides the actual url to use
+ String overrideUri = String.format("%s://%s/%s/%s", scheme, host, basePath, resolvedUriTemplate);
+ exchange.getIn().setHeader(Exchange.HTTP_URI, overrideUri);
+ }
+ }
+
+ public Swagger getSwagger() {
+ return swagger;
+ }
+
+ public void setSwagger(Swagger swagger) {
+ this.swagger = swagger;
+ }
+
+ @Override
+ protected void doStart() throws Exception {
+ super.doStart();
+
+ String verb = getEndpoint().getVerb();
+ String path = getEndpoint().getPath();
+
+ operation = getSwaggerOperation(verb, path);
+ if (operation == null) {
+ throw new IllegalArgumentException("Swagger schema does not contain operation for " + verb + ":" + path);
+ }
+
+ Producer processor = createHttpProducer(operation, verb, path);
+ if (processor != null) {
+ producer = AsyncProcessorConverterHelper.convert(processor);
+ }
+ ServiceHelper.startService(producer);
+ }
+
+ @Override
+ protected void doStop() throws Exception {
+ super.doStop();
+
+ ServiceHelper.stopService(producer);
+ }
+
private Operation getSwaggerOperation(String verb, String path) {
Path modelPath = swagger.getPath(path);
if (modelPath == null) {
@@ -119,15 +196,10 @@ public class SwaggerProducer extends DefaultAsyncProducer {
return op;
}
- public Swagger getSwagger() {
- return swagger;
- }
+ private Producer createHttpProducer(Operation operation, String verb, String path) throws Exception {
- public void setSwagger(Swagger swagger) {
- this.swagger = swagger;
- }
+ LOG.debug("Using Swagger operation: {} with {} {}", operation, verb, path);
- protected Producer createHttpProducer(Exchange exchange, Operation operation, String verb, String path) throws Exception {
RestProducerFactory factory = null;
String cname = null;
if (getEndpoint().getComponentName() != null) {
@@ -172,6 +244,7 @@ public class SwaggerProducer extends DefaultAsyncProducer {
}
if (factory != null) {
+ LOG.debug("Using RestProducerFactory: {}", factory);
CollectionStringBuffer produces = new CollectionStringBuffer(",");
List<String> list = operation.getProduces();
@@ -200,46 +273,8 @@ public class SwaggerProducer extends DefaultAsyncProducer {
String basePath = swagger.getBasePath();
String uriTemplate = path;
- // uri template with path parameters resolved
- String resolvedUriTemplate = uriTemplate;
- // for query parameters
- Map<String, Object> query = new LinkedHashMap<>();
- for (Parameter param : operation.getParameters()) {
- if ("query".equals(param.getIn())) {
- String name = param.getName();
- if (name != null) {
- String value = exchange.getIn().getHeader(name, String.class);
- if (value != null) {
- // we need to remove the header as they are sent as query instead
- // TODO: we could use a header filter strategy to skip these headers
- exchange.getIn().removeHeader(param.getName());
- query.put(name, value);
- } else if (param.getRequired()) {
- throw new NoSuchHeaderException(exchange, name, String.class);
- }
- }
- } else if ("path".equals(param.getIn())) {
- String value = exchange.getIn().getHeader(param.getName(), String.class);
- if (value != null) {
- // we need to remove the header as they are sent as path instead
- // TODO: we could use a header filter strategy to skip these headers
- exchange.getIn().removeHeader(param.getName());
- String token = "{" + param.getName() + "}";
- resolvedUriTemplate = StringHelper.replaceAll(resolvedUriTemplate, token, value);
- } else if (param.getRequired()) {
- // the parameter is required but we do not have a header
- throw new NoSuchHeaderException(exchange, param.getName(), String.class);
- }
- }
- }
- // build as query string
- String queryParameters = null;
- if (!query.isEmpty()) {
- queryParameters = URISupport.createQueryString(query);
- }
-
- return factory.createProducer(getEndpoint().getCamelContext(), exchange, scheme, host, verb, basePath, uriTemplate, resolvedUriTemplate,
- queryParameters, (consumes.isEmpty() ? "" : consumes.toString()), (produces.isEmpty() ? "" : produces.toString()), null);
+ return factory.createProducer(getEndpoint().getCamelContext(), scheme, host, verb, basePath, uriTemplate,
+ (consumes.isEmpty() ? "" : consumes.toString()), (produces.isEmpty() ? "" : produces.toString()), null);
} else {
throw new IllegalStateException("Cannot find RestProducerFactory in Registry or as a Component to use");
http://git-wip-us.apache.org/repos/asf/camel/blob/69c12a0a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java
----------------------------------------------------------------------
diff --git a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java
index 4f1da5c..499dd7e 100644
--- a/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java
+++ b/components/camel-swagger-java/src/test/java/org/apache/camel/swagger/component/DummyRestProducerFactory.java
@@ -29,8 +29,8 @@ import org.apache.camel.util.ObjectHelper;
public class DummyRestProducerFactory implements RestProducerFactory {
@Override
- public Producer createProducer(CamelContext camelContext, Exchange exchange, String scheme, String host,
- String verb, String basePath, final String uriTemplate, final String resolvedUriTemplate, final String queryParameters,
+ public Producer createProducer(CamelContext camelContext, String scheme, String host,
+ String verb, String basePath, final String uriTemplate,
String consumes, String produces, Map<String, Object> parameters) throws Exception {
// use a dummy endpoint
@@ -39,15 +39,17 @@ public class DummyRestProducerFactory implements RestProducerFactory {
return new DefaultProducer(endpoint) {
@Override
public void process(Exchange exchange) throws Exception {
- // for testing purpose, check if we have {name} in template
- if (uriTemplate.contains("{name}")) {
- int pos = resolvedUriTemplate.lastIndexOf('/');
- String name = resolvedUriTemplate.substring(pos + 1);
- exchange.getIn().setBody("Hello " + name);
- } else if (queryParameters.contains("name=")) {
- String name = ObjectHelper.after(queryParameters, "name=");
+ String query = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
+ if (query != null) {
+ String name = ObjectHelper.after(query, "name=");
exchange.getIn().setBody("Bye " + name);
}
+ String uri = exchange.getIn().getHeader(Exchange.HTTP_URI, String.class);
+ if (uri != null) {
+ int pos = uri.lastIndexOf('/');
+ String name = uri.substring(pos + 1);
+ exchange.getIn().setBody("Hello " + name);
+ }
}
};
}