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 2019/12/03 13:11:02 UTC
[camel] branch master updated: [CAMEL-13213] Cannot use
rest-swagger component with swagger.json provided over HTTPS protocol
(#3374)
This is an automated email from the ASF dual-hosted git repository.
davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git
The following commit(s) were added to refs/heads/master by this push:
new 0c2aa42 [CAMEL-13213] Cannot use rest-swagger component with swagger.json provided over HTTPS protocol (#3374)
0c2aa42 is described below
commit 0c2aa42dcba4a1a02044622bdf474cb51c4e0629
Author: JiriOndrusek <jo...@redhat.com>
AuthorDate: Tue Dec 3 14:10:50 2019 +0100
[CAMEL-13213] Cannot use rest-swagger component with swagger.json provided over HTTPS protocol (#3374)
---
components/camel-rest-swagger/pom.xml | 11 ++--
.../src/main/docs/rest-swagger-component.adoc | 3 +-
.../rest/swagger/RestSwaggerEndpoint.java | 76 ++++++++++++++++++----
.../camel/component/rest/swagger/HttpsTest.java | 19 +++++-
.../rest/swagger/RestSwaggerEndpointTest.java | 4 +-
.../karaf/features/src/main/resources/features.xml | 1 +
6 files changed, 91 insertions(+), 23 deletions(-)
diff --git a/components/camel-rest-swagger/pom.xml b/components/camel-rest-swagger/pom.xml
index f9ea6f5..cd2f0a5 100644
--- a/components/camel-rest-swagger/pom.xml
+++ b/components/camel-rest-swagger/pom.xml
@@ -71,6 +71,11 @@
</exclusions>
</dependency>
+ <dependency>
+ <groupId>org.apache.camel</groupId>
+ <artifactId>camel-http</artifactId>
+ </dependency>
+
<!-- test -->
<dependency>
<groupId>org.apache.camel</groupId>
@@ -123,12 +128,6 @@
<dependency>
<groupId>org.apache.camel</groupId>
- <artifactId>camel-http</artifactId>
- <scope>test</scope>
- </dependency>
-
- <dependency>
- <groupId>org.apache.camel</groupId>
<artifactId>camel-netty-http</artifactId>
<scope>test</scope>
</dependency>
diff --git a/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc b/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
index 844d9b6..fddde2a 100644
--- a/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
+++ b/components/camel-rest-swagger/src/main/docs/rest-swagger-component.adoc
@@ -126,7 +126,7 @@ with the following path and query parameters:
|===
-=== Query Parameters (8 parameters):
+=== Query Parameters (9 parameters):
[width="100%",cols="2,5,^1,2",options="header"]
@@ -140,6 +140,7 @@ with the following path and query parameters:
| *produces* (producer) | What payload type this component is producing. For example application/json according to the RFC7231. This equates to the value of Content-Type HTTP header. If set overrides any value present in the Swagger specification. Overrides all other configuration. | | String
| *basicPropertyBinding* (advanced) | Whether the endpoint should use basic property binding (Camel 2.x) or the newer property binding with additional capabilities | false | boolean
| *synchronous* (advanced) | Sets whether synchronous processing should be strictly used, or Camel is allowed to use asynchronous processing (if supported). | false | boolean
+| *sslContextParameters* (security) | To configure security using SSLContextParameters. | | SSLContextParameters
|===
// endpoint options: END
// spring-boot-auto-configure options: START
diff --git a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
index 8245b28..5e94d11 100644
--- a/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
+++ b/components/camel-rest-swagger/src/main/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpoint.java
@@ -51,6 +51,9 @@ import org.apache.camel.Endpoint;
import org.apache.camel.ExchangePattern;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
+import org.apache.camel.component.http.HttpComponent;
+import org.apache.camel.component.http.HttpEndpoint;
+import org.apache.camel.component.http.HttpProducer;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.RestConfiguration;
import org.apache.camel.spi.UriEndpoint;
@@ -58,9 +61,11 @@ import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriPath;
import org.apache.camel.support.DefaultEndpoint;
import org.apache.camel.support.ResourceHelper;
+import org.apache.camel.support.jsse.SSLContextParameters;
import org.apache.camel.util.ObjectHelper;
import org.apache.camel.util.StringHelper;
import org.apache.camel.util.UnsafeUriCharactersEncoder;
+import org.apache.http.client.methods.HttpGet;
import static java.util.Optional.ofNullable;
import static org.apache.camel.component.rest.swagger.RestSwaggerHelper.isHostParam;
@@ -123,6 +128,9 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
+ " any value present in the Swagger specification. Overrides all other configuration.", label = "producer")
private String produces;
+ @UriParam(label = "security", description = "To configure security using SSLContextParameters.")
+ private SSLContextParameters sslContextParameters;
+
@UriPath(description = "Path to the Swagger specification file. The scheme, host base path are taken from this"
+ " specification, but these can be overridden with properties on the component or endpoint level. If not"
+ " given the component tries to load `swagger.json` resource from the classpath. Note that the `host` defined on the"
@@ -165,7 +173,8 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
@Override
public Producer createProducer() throws Exception {
final CamelContext camelContext = getCamelContext();
- final Swagger swagger = loadSpecificationFrom(camelContext, specificationUri);
+
+ final Swagger swagger = loadSpecificationFrom(camelContext, specificationUri, resolveSslContextParameters());
final Map<String, Path> paths = swagger.getPaths();
@@ -200,6 +209,16 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
+ "`. Operations defined in the specification are: " + supportedOperations);
}
+ private SSLContextParameters resolveSslContextParameters() {
+ if (sslContextParameters != null) {
+ return sslContextParameters;
+ }
+ if (component().getSslContextParameters() != null) {
+ return component().getSslContextParameters();
+ }
+ return component().retrieveGlobalSslContextParameters();
+ }
+
public String getBasePath() {
return basePath;
}
@@ -212,6 +231,10 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
return consumes;
}
+ public SSLContextParameters getSslContextParameters() {
+ return sslContextParameters;
+ }
+
public String getHost() {
return host;
}
@@ -245,6 +268,10 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
this.consumes = isMediaRange(consumes, "consumes");
}
+ public void setSslContextParameters(SSLContextParameters sslContextParameters) {
+ this.sslContextParameters = sslContextParameters;
+ }
+
public void setHost(final String host) {
this.host = isHostParam(host);
}
@@ -592,31 +619,53 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
* @return the specification
* @throws IOException
*/
- static Swagger loadSpecificationFrom(final CamelContext camelContext, final URI uri) throws IOException {
+ static Swagger loadSpecificationFrom(final CamelContext camelContext, final URI uri, SSLContextParameters sslContextParameters) throws IOException {
final ObjectMapper mapper = Json.mapper();
final SwaggerParser swaggerParser = new SwaggerParser();
final String uriAsString = uri.toString();
- try (InputStream stream = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, uriAsString)) {
- final JsonNode node = mapper.readTree(stream);
+ if (sslContextParameters == null) {
+ try (InputStream stream = ResourceHelper.resolveMandatoryResourceAsInputStream(camelContext, uriAsString)) {
+ return parseInputStream(swaggerParser, mapper, stream);
+ } catch (final Exception e) {
+ return loadSpecificationFallback(swaggerParser, uriAsString, e);
+ }
+ }
- return swaggerParser.read(node);
+ HttpComponent httpComponent = new HttpComponent();
+ httpComponent.setSslContextParameters(sslContextParameters);
+ httpComponent.setCamelContext(camelContext);
+ try (HttpEndpoint e = (HttpEndpoint)httpComponent.createEndpoint(uriAsString);
+ HttpProducer p = (HttpProducer)e.createProducer();
+ InputStream stream = p.getHttpClient().execute(new HttpGet(uri)).getEntity().getContent()) {
+
+ return parseInputStream(swaggerParser, mapper, stream);
} catch (final Exception e) {
- // try Swaggers loader
- final Swagger swagger = swaggerParser.read(uriAsString);
+ return loadSpecificationFallback(swaggerParser, uriAsString, e);
+ }
+ }
- if (swagger != null) {
- return swagger;
- }
+ static Swagger loadSpecificationFallback(SwaggerParser swaggerParser, String uriAsString, Exception originalException) {
+ // try Swaggers loader
+ final Swagger swagger = swaggerParser.read(uriAsString);
+
+ if (swagger != null) {
+ return swagger;
+ }
- throw new IllegalArgumentException("The given Swagger specification could not be loaded from `" + uri
+ throw new IllegalArgumentException("The given Swagger specification could not be loaded from `" + uriAsString
+ "`. Tried loading using Camel's resource resolution and using Swagger's own resource resolution."
+ " Swagger tends to swallow exceptions while parsing, try specifying Java system property `debugParser`"
+ " (e.g. `-DdebugParser=true`), the exception that occurred when loading using Camel's resource"
- + " loader follows", e);
- }
+ + " loader follows", originalException);
+ }
+
+ static Swagger parseInputStream(SwaggerParser swaggerParser, ObjectMapper mapper, InputStream stream) throws IOException {
+ final JsonNode node = mapper.readTree(stream);
+
+ return swaggerParser.read(node);
}
static String pickBestScheme(final String specificationScheme, final List<Scheme> schemes) {
@@ -651,4 +700,5 @@ public final class RestSwaggerEndpoint extends DefaultEndpoint {
return expression.toString();
}
+
}
diff --git a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/HttpsTest.java b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/HttpsTest.java
index 4e53c40..33638a7 100644
--- a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/HttpsTest.java
+++ b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/HttpsTest.java
@@ -94,6 +94,20 @@ public abstract class HttpsTest extends CamelTestSupport {
equalTo("application/xml, application/json")));
}
+
+ @Test
+ public void swaggerJsonOverHttps() throws Exception {
+ final Pet pet = template.requestBodyAndHeader("direct:httpsJsonGetPetById", NO_BODY, "petId", 14, Pet.class);
+
+ assertNotNull(pet);
+
+ assertEquals(Integer.valueOf(14), pet.id);
+ assertEquals("Olafur Eliason Arnalds", pet.name);
+
+ petstore.verify(getRequestedFor(urlEqualTo("/v2/pet/14")).withHeader("Accept",
+ equalTo("application/xml, application/json")));
+ }
+
@Override
protected CamelContext createCamelContext() throws Exception {
final CamelContext camelContext = super.createCamelContext();
@@ -101,9 +115,10 @@ public abstract class HttpsTest extends CamelTestSupport {
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setComponentName(componentName);
component.setHost("https://localhost:" + petstore.httpsPort());
+ component.setUseGlobalSslContextParameters(true);
camelContext.addComponent("petStore", component);
-
+ camelContext.setSSLContextParameters(createHttpsParameters(camelContext));
return camelContext;
}
@@ -119,6 +134,8 @@ public abstract class HttpsTest extends CamelTestSupport {
jaxb.setJaxbProviderProperties(Collections.singletonMap(Marshaller.JAXB_FORMATTED_OUTPUT, false));
from("direct:getPetById").to("petStore:getPetById").unmarshal(jaxb);
+
+ from("direct:httpsJsonGetPetById").to("petStore:https://localhost:" + petstore.httpsPort() + "/swagger.json#getPetById").unmarshal(jaxb);
}
};
}
diff --git a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
index 8b4b432..42c3cd6 100644
--- a/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
+++ b/components/camel-rest-swagger/src/test/java/org/apache/camel/component/rest/swagger/RestSwaggerEndpointTest.java
@@ -338,7 +338,7 @@ public class RestSwaggerEndpointTest {
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
assertThat(
- RestSwaggerEndpoint.loadSpecificationFrom(camelContext, RestSwaggerComponent.DEFAULT_SPECIFICATION_URI))
+ RestSwaggerEndpoint.loadSpecificationFrom(camelContext, RestSwaggerComponent.DEFAULT_SPECIFICATION_URI, null))
.isNotNull();
}
@@ -363,7 +363,7 @@ public class RestSwaggerEndpointTest {
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
- RestSwaggerEndpoint.loadSpecificationFrom(camelContext, URI.create("non-existant.json"));
+ RestSwaggerEndpoint.loadSpecificationFrom(camelContext, URI.create("non-existant.json"), null);
}
@Test
diff --git a/platforms/karaf/features/src/main/resources/features.xml b/platforms/karaf/features/src/main/resources/features.xml
index 5b7d2ac..13cb2d4 100644
--- a/platforms/karaf/features/src/main/resources/features.xml
+++ b/platforms/karaf/features/src/main/resources/features.xml
@@ -2083,6 +2083,7 @@
</feature> -->
<feature name='camel-rest-swagger' version='${project.version}' start-level='50'>
<feature version='${project.version}'>camel-core</feature>
+ <feature version='${project.version}'>camel-http</feature>
<bundle dependency='true'>mvn:org.yaml/snakeyaml/${snakeyaml-version}</bundle>
<bundle dependency='true'>mvn:javax.validation/validation-api/${validation-1-api-version}</bundle>
<bundle dependency='true'>mvn:com.fasterxml.jackson.core/jackson-core/${jackson2-version}</bundle>