/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 at
*
* 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.
*/
package org.apache.camel.component.rest.swagger;
import java.io.IOException;
import java.net.URI;
import java.util.Arrays;
import java.util.Collections;
import io.swagger.models.Operation;
import io.swagger.models.Scheme;
import io.swagger.models.Swagger;
import io.swagger.models.parameters.QueryParameter;
import org.apache.camel.CamelContext;
import org.apache.camel.Endpoint;
import org.apache.camel.Producer;
import org.apache.camel.impl.DefaultClassResolver;
import org.apache.camel.spi.RestConfiguration;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class RestSwaggerEndpointTest {
URI componentJsonUri = URI.create("component.json");
URI endpointUri = URI.create("endpoint.json");
@Test(expected = IllegalArgumentException.class)
public void shouldComplainForUnknownOperations() throws Exception {
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
final RestSwaggerComponent component = new RestSwaggerComponent(camelContext);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:unknown", "unknown", component);
endpoint.createProducer();
}
@Test
public void shouldCreateProducers() throws Exception {
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
final Endpoint endpointDelegate = mock(Endpoint.class);
when(camelContext.getEndpoint("rest:GET:/v2:/pet/{petId}")).thenReturn(endpointDelegate);
final Producer delegateProducer = mock(Producer.class);
when(endpointDelegate.createProducer()).thenReturn(delegateProducer);
final RestSwaggerComponent component = new RestSwaggerComponent(camelContext);
component.setHost("http://petstore.swagger.io");
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:getPetById", "getPetById",
component);
final Producer producer = endpoint.createProducer();
assertThat(producer).isSameAs(delegateProducer);
}
@Test
public void shouldCreateQueryParameterExpressions() {
assertThat(RestSwaggerEndpoint.queryParameterExpression(new QueryParameter())).isEmpty();
assertThat(RestSwaggerEndpoint.queryParameterExpression(new QueryParameter().name("q").required(true)))
.isEqualTo("q={q}");
assertThat(RestSwaggerEndpoint.queryParameterExpression(new QueryParameter().name("q").required(false)))
.isEqualTo("q={q?}");
}
@Test
public void shouldDetermineBasePath() {
final RestConfiguration restConfiguration = new RestConfiguration();
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getRestConfiguration("rest-swagger", true)).thenReturn(restConfiguration);
final Swagger swagger = new Swagger();
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setCamelContext(camelContext);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:getPetById", "getPetById",
component);
assertThat(endpoint.determineBasePath(swagger))
.as("When no base path is specified on component, endpoint or rest configuration it should default to `/`")
.isEqualTo("/");
restConfiguration.setContextPath("/rest");
assertThat(endpoint.determineBasePath(swagger))
.as("When base path is specified in REST configuration and not specified in component the base path should be from the REST configuration")
.isEqualTo("/rest");
swagger.basePath("/specification");
assertThat(endpoint.determineBasePath(swagger))
.as("When base path is specified in the specification it should take precedence the one specified in the REST configuration")
.isEqualTo("/specification");
component.setBasePath("/component");
assertThat(endpoint.determineBasePath(swagger))
.as("When base path is specified on the component it should take precedence over Swagger specification and REST configuration")
.isEqualTo("/component");
endpoint.setBasePath("/endpoint");
assertThat(endpoint.determineBasePath(swagger))
.as("When base path is specified on the endpoint it should take precedence over any other")
.isEqualTo("/endpoint");
}
@Test
public void shouldDetermineEndpointParameters() {
final CamelContext camelContext = mock(CamelContext.class);
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setCamelContext(camelContext);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("uri", "remaining", component);
endpoint.setHost("http://petstore.swagger.io");
final Swagger swagger = new Swagger();
final Operation operation = new Operation();
assertThat(endpoint.determineEndpointParameters(swagger, operation))
.containsOnly(entry("host", "http://petstore.swagger.io"));
component.setComponentName("xyz");
assertThat(endpoint.determineEndpointParameters(swagger, operation))
.containsOnly(entry("host", "http://petstore.swagger.io"), entry("componentName", "xyz"));
swagger.consumes("application/json").produces("application/xml");
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "xyz"),
entry("consumes", "application/xml"), entry("produces", "application/json"));
component.setProduces("application/json");
component.setConsumes("application/atom+xml");
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "xyz"),
entry("consumes", "application/atom+xml"), entry("produces", "application/json"));
endpoint.setProduces("application/atom+xml");
endpoint.setConsumes("application/json");
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "xyz"),
entry("consumes", "application/json"), entry("produces", "application/atom+xml"));
endpoint.setComponentName("zyx");
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "zyx"),
entry("consumes", "application/json"), entry("produces", "application/atom+xml"));
operation.addParameter(new QueryParameter().name("q").required(true));
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "zyx"),
entry("consumes", "application/json"), entry("produces", "application/atom+xml"),
entry("queryParameters", "q={q}"));
operation.addParameter(new QueryParameter().name("o"));
assertThat(endpoint.determineEndpointParameters(swagger, operation)).containsOnly(
entry("host", "http://petstore.swagger.io"), entry("componentName", "zyx"),
entry("consumes", "application/json"), entry("produces", "application/atom+xml"),
entry("queryParameters", "q={q}&o={o?}"));
}
@Test
public void shouldDetermineHostFromRestConfiguration() {
assertThat(RestSwaggerEndpoint.hostFrom(null)).isNull();
final RestConfiguration configuration = new RestConfiguration();
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isNull();
configuration.setScheme("ftp");
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isNull();
configuration.setScheme("http");
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isNull();
configuration.setHost("petstore.swagger.io");
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isEqualTo("http://petstore.swagger.io");
configuration.setPort(80);
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isEqualTo("http://petstore.swagger.io");
configuration.setPort(8080);
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isEqualTo("http://petstore.swagger.io:8080");
configuration.setScheme("https");
configuration.setPort(80);
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isEqualTo("https://petstore.swagger.io:80");
configuration.setPort(443);
assertThat(RestSwaggerEndpoint.hostFrom(configuration)).isEqualTo("https://petstore.swagger.io");
}
@Test
public void shouldDetermineHostFromSpecification() {
final RestSwaggerComponent component = new RestSwaggerComponent();
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:http://some-uri#getPetById",
"http://some-uri#getPetById", component);
final Swagger swagger = new Swagger();
swagger.host("petstore.swagger.io");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://petstore.swagger.io");
swagger.schemes(Arrays.asList(Scheme.HTTPS));
assertThat(endpoint.determineHost(swagger)).isEqualTo("https://petstore.swagger.io");
}
@Test
public void shouldDetermineOptions() {
assertThat(RestSwaggerEndpoint.determineOption(null, null, null, null)).isNull();
assertThat(RestSwaggerEndpoint.determineOption(Collections.emptyList(), Collections.emptyList(), "", ""))
.isNull();
assertThat(RestSwaggerEndpoint.determineOption(Arrays.asList("specification"), null, null, null))
.isEqualTo("specification");
assertThat(
RestSwaggerEndpoint.determineOption(Arrays.asList("specification"), Arrays.asList("operation"), null, null))
.isEqualTo("operation");
assertThat(RestSwaggerEndpoint.determineOption(Arrays.asList("specification"), Arrays.asList("operation"),
"component", null)).isEqualTo("component");
assertThat(RestSwaggerEndpoint.determineOption(Arrays.asList("specification"), Arrays.asList("operation"),
"component", "operation")).isEqualTo("operation");
}
@Test
public void shouldHonourComponentSpecificationPathProperty() throws Exception {
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setSpecificationUri(componentJsonUri);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:getPetById", "getPetById",
component);
assertThat(endpoint.getSpecificationUri()).isEqualTo(componentJsonUri);
}
@Test
public void shouldHonourEndpointUriPathSpecificationPathProperty() throws Exception {
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setSpecificationUri(componentJsonUri);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:endpoint.json#getPetById",
"endpoint.json#getPetById", component);
assertThat(endpoint.getSpecificationUri()).isEqualTo(endpointUri);
}
@Test
public void shouldHonourHostPrecedence() {
final RestConfiguration globalRestConfiguration = new RestConfiguration();
final RestConfiguration componentRestConfiguration = new RestConfiguration();
final RestConfiguration specificRestConfiguration = new RestConfiguration();
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getRestConfiguration()).thenReturn(globalRestConfiguration);
when(camelContext.getRestConfiguration("rest-swagger", false)).thenReturn(componentRestConfiguration);
when(camelContext.getRestConfiguration("petstore", false)).thenReturn(specificRestConfiguration);
final RestSwaggerComponent component = new RestSwaggerComponent();
component.setCamelContext(camelContext);
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("petstore:http://specification-uri#getPetById",
"http://specification-uri#getPetById", component);
final Swagger swagger = new Swagger();
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://specification-uri");
globalRestConfiguration.setHost("global-rest");
globalRestConfiguration.setScheme("http");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://global-rest");
globalRestConfiguration.setHost("component-rest");
globalRestConfiguration.setScheme("http");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://component-rest");
specificRestConfiguration.setHost("specific-rest");
specificRestConfiguration.setScheme("http");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://specific-rest");
swagger.host("specification").scheme(Scheme.HTTP);
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://specification");
component.setHost("http://component");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://component");
endpoint.setHost("http://endpoint");
assertThat(endpoint.determineHost(swagger)).isEqualTo("http://endpoint");
}
@Test
public void shouldLoadSwaggerSpecifications() throws IOException {
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
assertThat(
RestSwaggerEndpoint.loadSpecificationFrom(camelContext, RestSwaggerComponent.DEFAULT_SPECIFICATION_URI))
.isNotNull();
}
@Test
public void shouldPickBestScheme() {
assertThat(RestSwaggerEndpoint.pickBestScheme("http", Arrays.asList(Scheme.HTTP, Scheme.HTTPS)))
.isEqualTo("https");
assertThat(RestSwaggerEndpoint.pickBestScheme("https", Arrays.asList(Scheme.HTTP))).isEqualTo("http");
assertThat(RestSwaggerEndpoint.pickBestScheme("http", Collections.emptyList())).isEqualTo("http");
assertThat(RestSwaggerEndpoint.pickBestScheme("http", null)).isEqualTo("http");
assertThat(RestSwaggerEndpoint.pickBestScheme(null, Collections.emptyList())).isNull();
assertThat(RestSwaggerEndpoint.pickBestScheme(null, null)).isNull();
}
@Test(expected = IllegalArgumentException.class)
public void shouldRaiseExceptionsForMissingSpecifications() throws IOException {
final CamelContext camelContext = mock(CamelContext.class);
when(camelContext.getClassResolver()).thenReturn(new DefaultClassResolver());
RestSwaggerEndpoint.loadSpecificationFrom(camelContext, URI.create("non-existant.json"));
}
@Test
public void shouldUseDefaultSpecificationUri() throws Exception {
final RestSwaggerComponent component = new RestSwaggerComponent();
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:getPetById", "getPetById",
component);
assertThat(endpoint.getSpecificationUri()).isEqualTo(RestSwaggerComponent.DEFAULT_SPECIFICATION_URI);
}
@Test
public void shouldUseDefaultSpecificationUriEvenIfHashIsPresent() throws Exception {
final RestSwaggerComponent component = new RestSwaggerComponent();
final RestSwaggerEndpoint endpoint = new RestSwaggerEndpoint("rest-swagger:#getPetById", "#getPetById",
component);
assertThat(endpoint.getSpecificationUri()).isEqualTo(RestSwaggerComponent.DEFAULT_SPECIFICATION_URI);
}
}