/**
* 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.impl;
import java.util.Map;
import java.util.SortedMap;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Consumer;
import org.apache.camel.Endpoint;
import org.apache.camel.InvalidPropertyException;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.ResolveEndpointFailedException;
import org.apache.camel.TestSupport;
import org.apache.camel.component.seda.SedaComponent;
import org.apache.camel.component.seda.SedaEndpoint;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
/**
* Tests the use of {@link ComponentConfiguration} both from the URI string approach or for creating and mutating Endpoint instances
* with both regular Components/Endpoints and {@link UriEndpointComponent} instances which have Endpoints annotated
* with {@link org.apache.camel.spi.UriEndpoint}, {@link org.apache.camel.spi.UriParam} and {@link org.apache.camel.spi.UriParams}
*/
public class ComponentConfigurationTest {
private static final Logger LOG = LoggerFactory.getLogger(ComponentConfigurationTest.class);
private CamelContext context;
@Before
public void createContext() throws Exception {
context = new DefaultCamelContext();
context.addComponent("cheese", new NonUriComponent());
context.start(); // so that TypeConverters are available
}
@After
public void destroyContext() throws Exception {
context.stop();
context = null;
}
/**
* Show we can create a URI from the base URI and the underlying query parameter values
*/
@Test
public void testCreateUriStringFromParameters() throws Exception {
Component component = context.getComponent("seda");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the base URI properties
configuration.setBaseUri("foo");
// lets try set and get a valid parameter
configuration.setParameter("concurrentConsumers", 5);
configuration.setParameter("size", 1000);
String uriString = configuration.getUriString();
assertEquals("uriString", "foo?concurrentConsumers=5&size=1000", uriString);
}
/**
* Show we can create a URI from the base URI and the underlying query parameter values
* on any endpoint (even if its not a {@link UriEndpointComponent})
*/
@Test
public void testCreateUriStringFromParametersOnDefaultComponent() throws Exception {
Component component = context.getComponent("cheese");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the base URI properties
configuration.setBaseUri("somePath");
// lets try set and get a valid parameter
configuration.setParameter("foo", "something");
configuration.setParameter("bar", 123);
String uriString = configuration.getUriString();
assertEquals("uriString", "somePath?bar=123&foo=something", uriString);
}
/**
* Test that parameters are strictly typed on {@link UriEndpointComponent}s
*/
@Test
public void testSetParametersFromUriString() throws Exception {
Component component = context.getComponent("seda");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the uri and query parameters
configuration.setUriString("foo?concurrentConsumers=5&size=1000");
// notice the parameters are all correctly typed due to the use of a UriEndpointComponent
// and the associated @UriEndpoint / @UriParam annotations
assertEquals("concurrentConsumers", 5, configuration.getParameter("concurrentConsumers"));
assertEquals("size", 1000, configuration.getParameter("size"));
configuration.setUriString("foo?concurrentConsumers=9&size=2000");
assertEquals("concurrentConsumers", 9, configuration.getParameter("concurrentConsumers"));
assertEquals("size", 2000, configuration.getParameter("size"));
}
/**
* Tests that parameters can be used on non-{@link UriEndpointComponent} implementations
* but that their types tend to be String until we try to create an Endpoint
*/
@Test
public void testSetParametersFromUriStringOnDefaultComponent() throws Exception {
Component component = context.getComponent("cheese");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the uri and query parameters
configuration.setUriString("somePath?foo=something&bar=123");
// notice the parameters are all Strings since we don't use UriEndpointComponent
assertEquals("foo", "something", configuration.getParameter("foo"));
assertEquals("bar", "123", configuration.getParameter("bar"));
configuration.setUriString("somePath?foo=another&bar=456");
assertEquals("foo", "another", configuration.getParameter("foo"));
assertEquals("bar", "456", configuration.getParameter("bar"));
}
/**
* Use the {@link ComponentConfiguration}, set some parameters then lets turn it into an endpoint
*/
@Test
public void testCreateNewSedaUriEndpoint() throws Exception {
Component component = context.getComponent("seda");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the base URI properties
configuration.setBaseUri("foo");
// lets try set and get a valid parameter
configuration.setParameter("concurrentConsumers", 5);
configuration.setParameter("size", 1000);
// lets try set an invalid parameter
try {
configuration.setParameter("doesNotExist", 1000);
fail("Should have got InvalidPropertyException thrown!");
} catch (InvalidPropertyException e) {
LOG.info("Got expected exception: " + e);
}
SedaEndpoint endpoint = TestSupport
.assertIsInstanceOf(SedaEndpoint.class, configuration.createEndpoint());
assertEquals("concurrentConsumers", 5, endpoint.getConcurrentConsumers());
assertEquals("size", 1000, endpoint.getSize());
assertEquals("endpoint uri", "foo?concurrentConsumers=5&size=1000", endpoint.getEndpointUri());
// lets try configure a parameter
configuration.setEndpointParameter(endpoint, "concurrentConsumers", 6);
assertEquals("concurrentConsumers", 6, endpoint.getConcurrentConsumers());
// lets try set an invalid parameter
try {
configuration.setEndpointParameter(endpoint, "doesNotExist", 1000);
fail("Should have got InvalidPropertyException thrown!");
} catch (InvalidPropertyException e) {
LOG.info("Got expected exception: " + e);
}
}
@Test
public void testCreateNewDefaultComponentEndpoint() throws Exception {
Component component = context.getComponent("cheese");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
// configure the base URI properties
configuration.setBaseUri("something");
// lets try set and get a valid parameter
configuration.setParameter("foo", "xyz");
configuration.setParameter("bar", 5);
NonUriEndpoint endpoint = TestSupport
.assertIsInstanceOf(NonUriEndpoint.class, configuration.createEndpoint());
assertEquals("foo", "xyz", endpoint.getFoo());
assertEquals("bar", 5, endpoint.getBar());
LOG.info("Created endpoint " + endpoint + " on URI " + endpoint.getEndpointUri());
// lets try configure a parameter
configuration.setEndpointParameter(endpoint, "bar", 6);
assertEquals("bar", 6, endpoint.getBar());
// lets try configure an invalid parameter
try {
configuration.setEndpointParameter(endpoint, "doesNotExist", 1000);
fail("Should have got InvalidPropertyException thrown!");
} catch (InvalidPropertyException e) {
LOG.info("Got expected exception: " + e);
}
ComponentConfiguration badConfiguration = component.createComponentConfiguration();
badConfiguration.setBaseUri(configuration.getBaseUri());
badConfiguration.setParameters(configuration.getParameters());
// lets try set an invalid parameter on a configuration
// there is no way to validate on non UriEndpoint unless the endpoint
// creates its own configuration object so this always works...
badConfiguration.setParameter("doesNotExist", 1000);
// however it fails if we now try create an
try {
badConfiguration.createEndpoint();
fail("Should have got ResolveEndpointFailedException thrown!");
} catch (ResolveEndpointFailedException e) {
LOG.info("Got expected exception: " + e);
}
}
/**
* Shows we can introspect a {@link UriEndpointComponent} and find all the available parameters
* along with their types and {@link ParameterConfiguration}
*/
@Test
public void testIntrospectSedaEndpointParameters() throws Exception {
Component component = context.getComponent("seda");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
SortedMap<String, ParameterConfiguration> parameterMap = configuration.getParameterConfigurationMap();
assertTrue("getParameterConfigurationMap() should not be empty!", !parameterMap.isEmpty());
ParameterConfiguration concurrentConsumersConfig = parameterMap.get("concurrentConsumers");
assertNotNull("parameterMap[concurrentConsumers] should not be null!", concurrentConsumersConfig);
assertEquals("concurrentConsumersConfig.getName()", "concurrentConsumers",
concurrentConsumersConfig.getName());
assertEquals("concurrentConsumersConfig.getParameterType()", int.class,
concurrentConsumersConfig.getParameterType());
LOG.info("{} has has configuration properties {}", component, parameterMap.keySet());
}
/**
* Shows we can introspect the parameters of a DefaultComponent (i.e. a non {@link UriEndpointComponent})
* though we only get to introspect the parameter values from teh current configuration
*/
@Test
public void testIntrospectDefaultComponentParameters() throws Exception {
Component component = context.getComponent("cheese");
ComponentConfiguration configuration = component.createComponentConfiguration();
assertNotNull("Should have created a ComponentConfiguration for component " + component,
configuration);
SortedMap<String, ParameterConfiguration> parameterMap = configuration.getParameterConfigurationMap();
assertTrue("getParameterConfigurationMap() should be empty as we have no parameters yet",
parameterMap.isEmpty());
// configure the uri and query parameters
configuration.setUriString("somePath?foo=something&bar=123");
parameterMap = configuration.getParameterConfigurationMap();
assertEquals("getParameterConfigurationMap() size", 2, parameterMap.size());
ParameterConfiguration barConfiguration = configuration.getParameterConfiguration("bar");
assertNotNull("should hav a configuration for 'bar'", barConfiguration);
assertEquals("barConfiguration.getName()", "bar", barConfiguration.getName());
assertEquals("barConfiguration.getParameterType()", String.class,
barConfiguration.getParameterType());
}
/**
* Shows how we can use the configuration to get and set parameters directly on the endpoint
* for a {@link UriEndpointComponent}
*/
@Test
public void testConfigureAnExistingSedaEndpoint() throws Exception {
SedaEndpoint endpoint = context.getEndpoint("seda:cheese?concurrentConsumers=5", SedaEndpoint.class);
SedaComponent component = endpoint.getComponent();
ComponentConfiguration configuration = component.createComponentConfiguration();
assertEquals("concurrentConsumers", 5, endpoint.getConcurrentConsumers());
assertEquals("concurrentConsumers", 5,
configuration.getEndpointParameter(endpoint, "concurrentConsumers"));
// lets try set and get some valid parameters
configuration.setEndpointParameter(endpoint, "concurrentConsumers", 10);
Object concurrentConsumers = configuration.getEndpointParameter(endpoint, "concurrentConsumers");
assertEquals("endpoint.concurrentConsumers", 10, concurrentConsumers);
configuration.setEndpointParameter(endpoint, "size", 1000);
Object size = configuration.getEndpointParameter(endpoint, "size");
assertEquals("endpoint.size", 1000, size);
// lets try set an invalid parameter
try {
configuration.setEndpointParameter(endpoint, "doesNotExist", 1000);
fail("Should have got InvalidPropertyException thrown!");
} catch (InvalidPropertyException e) {
LOG.info("Got expected exception: " + e);
}
}
/**
* Shows how we can use the configuration to get and set parameters directly on the endpoint
* which is typesafe and performs validation even if the component is not a {@link UriEndpointComponent}
*/
@Test
public void testConfigureAnExistingDefaultEndpoint() throws Exception {
NonUriEndpoint endpoint = context
.getEndpoint("cheese:somePath?bar=123&foo=something", NonUriEndpoint.class);
Component component = endpoint.getComponent();
ComponentConfiguration configuration = component.createComponentConfiguration();
assertEquals("bar", 123, endpoint.getBar());
assertEquals("bar", 123, configuration.getEndpointParameter(endpoint, "bar"));
// lets try set and get some valid parameters
configuration.setEndpointParameter(endpoint, "bar", 10);
Object bar = configuration.getEndpointParameter(endpoint, "bar");
assertEquals("endpoint.bar", 10, bar);
configuration.setEndpointParameter(endpoint, "foo", "anotherThing");
Object foo = configuration.getEndpointParameter(endpoint, "foo");
assertEquals("endpoint.foo", "anotherThing", foo);
// lets try set an invalid parameter
try {
configuration.setEndpointParameter(endpoint, "doesNotExist", 1000);
fail("Should have got InvalidPropertyException thrown!");
} catch (InvalidPropertyException e) {
LOG.info("Got expected exception: " + e);
}
}
public static class NonUriComponent extends DefaultComponent {
@Override
protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
return new NonUriEndpoint(uri, this);
}
}
public static class NonUriEndpoint extends DefaultEndpoint {
private String foo;
private int bar;
public NonUriEndpoint(String uri, NonUriComponent component) {
super(uri, component);
}
public int getBar() {
return bar;
}
public void setBar(int bar) {
this.bar = bar;
}
public String getFoo() {
return foo;
}
public void setFoo(String foo) {
this.foo = foo;
}
@Override
public Producer createProducer() throws Exception {
return null;
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
return null;
}
@Override
public boolean isSingleton() {
return false;
}
}
}