You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2013/04/23 10:00:09 UTC
svn commit: r1470840 - in /camel/trunk/camel-core/src:
main/java/org/apache/camel/ main/java/org/apache/camel/component/seda/
main/java/org/apache/camel/impl/ test/java/org/apache/camel/impl/
Author: jstrachan
Date: Tue Apr 23 08:00:07 2013
New Revision: 1470840
URL: http://svn.apache.org/r1470840
Log:
Initial implementation of CAMEL-6306 to add a ComponentConfiguration API on Component; which is like EndpointConfiguration but can be created on a Component and used to create (or edit) an Endpoint or a URI string. Also adds a UriEndpointComponent which is a handy base class for any endpoint which is annotated by @UriEndpoint so that it can return better metadata in its ComponentConfiguration implementation
Added:
camel/trunk/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java
- copied, changed from r1468302, camel/trunk/camel-core/src/main/java/org/apache/camel/EndpointConfiguration.java
camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java (with props)
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java (with props)
camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java (with props)
Modified:
camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java
camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaComponent.java
camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java
camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java
camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java?rev=1470840&r1=1470839&r2=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/Component.java Tue Apr 23 08:00:07 2013
@@ -60,4 +60,15 @@ public interface Component extends Camel
* @since Camel 2.9.0
*/
EndpointConfiguration createConfiguration(String uri) throws Exception;
+
+ /**
+ * Creates a configuration helper object for a component that lets you configure the various
+ * URI and parameter values; then create the full URI for it, create a new Endpoint from it
+ * or configure an existing Endpoint from the values.
+ *
+ * This method is intended to be used in cases where there is not yet a full URI to
+ * configure an endpoint yet; but rather there are a number of parameters to configure
+ * to then build up a new URI or directly create an Endpoint from the parameter values.
+ */
+ ComponentConfiguration createComponentConfiguration();
}
Copied: camel/trunk/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java (from r1468302, camel/trunk/camel-core/src/main/java/org/apache/camel/EndpointConfiguration.java)
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java?p2=camel/trunk/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java&p1=camel/trunk/camel-core/src/main/java/org/apache/camel/EndpointConfiguration.java&r1=1468302&r2=1470840&rev=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/EndpointConfiguration.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/ComponentConfiguration.java Tue Apr 23 08:00:07 2013
@@ -16,61 +16,126 @@
*/
package org.apache.camel;
-import java.net.URI;
+import org.apache.camel.impl.ParameterConfiguration;
+
+import java.net.URISyntaxException;
+import java.util.Map;
+import java.util.SortedMap;
/**
- * Holds an {@link Endpoint} configuration as a pojo that can be manipulated and validated.
- * Camel endpoint configuration is strongly related to URIs.
+ * Represents a set of configuration values for an endpoint URI which can be created from a URI string
+ * or a base URI string and a set of parameter names and values.
+ *
+ * The configuration values can then be introspected, modified and converted back into a URI string
+ * or Endpoint.
+ *
+ * For @{link UriEndpointComponent} implementations created for Endpoints annotated with {@link UriEndpoint} and the
+ * associated annotations then all the parameter values can be introspected and the parameter values are converted to their
+ * correct type.
+ *
+ * Other implementations keep all the types as String and there is no validation until you try to create
+ * an Endpoint from the values.
*/
-public interface EndpointConfiguration {
+public interface ComponentConfiguration {
- String URI_SCHEME = "scheme";
- String URI_SCHEME_SPECIFIC_PART = "schemeSpecificPart";
- String URI_AUTHORITY = "authority";
- String URI_USER_INFO = "userInfo";
- String URI_HOST = "host";
- String URI_PORT = "port";
- String URI_PATH = "path";
- String URI_QUERY = "query";
- String URI_FRAGMENT = "fragment";
+ /**
+ * Returns the base URI without any query parameters added
+ */
+ String getBaseUri();
+
+ /**
+ * Sets the base URI without any query parameters added
+ */
+ void setBaseUri(String baseUri);
+
+
+ /**
+ * Returns the current parameters of the configuration (usually encoded as ?foo=bar&whatnot=something URI query parameters)
+ */
+ Map<String, Object> getParameters();
/**
- * {@link org.apache.camel.spi.DataFormat} operations.
+ * Sets the parameter values of this configuration
*/
- public enum UriFormat {
- Canonical, Provider, Consumer, Complete
- }
+ void setParameters(Map<String, Object> propertyValues);
/**
- * Returns the URI configuration of an {@link Endpoint}.
+ * Returns the parameter value for the given name
*
- * @return the configuration URI.
+ * @param name the name of the URI query parameter to get
+ * @return the value of the parameter
*/
- URI getURI();
+ Object getParameter(String name);
/**
- * Gets the value of a particular parameter.
+ * Sets the parameter value of the given name
*
- * @param name the parameter name
- * @return the configuration URI.
- * @throws RuntimeCamelException is thrown if error getting the parameter
+ * @param name the name of the URI query parameter
+ * @param value the new value of the parameter
+ */
+ void setParameter(String name, Object value);
+
+
+ /**
+ * Returns the URI string (without schema) with query parameters for the current
+ * configuration which can then be used to create an {@link org.apache.camel.Endpoint}
*/
- <T> T getParameter(String name) throws RuntimeCamelException;
+ String getUriString();
/**
- * Sets the value of a particular parameter.
+ * Sets the URI string (without schema but with optional query parameters)
+ * which will update the {@link #getBaseUri()} and the {@link #getParameters()} values
*
- * @param name the parameter name
- * @param value the parameter value
- * @throws RuntimeCamelException is thrown if error setting the parameter
+ * @param newValue the new URI string with query arguments
*/
- <T> void setParameter(String name, T value) throws RuntimeCamelException;
+ void setUriString(String newValue) throws URISyntaxException;
/**
- * Returns the formatted configuration string of an {@link Endpoint}.
+ * Returns the URI query parameter configuration for the given parameter name or null if it does not exist
+ */
+ ParameterConfiguration getParameterConfiguration(String name);
+
+ /**
+ * Returns the sorted map of all the parameter names to their {@link ParameterConfiguration} objects
+ */
+ SortedMap<String, ParameterConfiguration> getParameterConfigurationMap();
+
+
+ /**
+ * Converts the configuration into a URI and then looks up the endpoint in the {@link CamelContext}
+ * which typically results in a new {@link Endpoint} instance being creatd.
+ */
+ Endpoint createEndpoint() throws Exception;
+
+ /**
+ * Applies the current set of parameters to the given endpoint instance.
+ * <p/>
+ * Note that typically parts of the URI are not injected into the Endpoint; this method purely
*
- * @param format the format
- * @return the configuration URI in String format.
+ * @param endpoint
*/
- String toUriString(UriFormat format);
+ void configureEndpoint(Endpoint endpoint);
+
+
+ /**
+ * Gets the named URI parameter value on the given endpoint
+ *
+ * @param endpoint the endpoint instance
+ * @param name the name of the URI query parameter
+ * @return the value of the parameter
+ * @throws RuntimeCamelException if the parameter name does not exist on the endpoint
+ */
+ Object getEndpointParameter(Endpoint endpoint, String name) throws RuntimeCamelException;
+
+ /**
+ * Sets the named URI query parameter value on the given endpoint
+ *
+ * @param endpoint the endpoint instance
+ * @param name the name of the URI query parameter
+ * @param value the new value of the URI query parameter
+ * @throws RuntimeCamelException
+ */
+ void setEndpointParameter(Endpoint endpoint, String name, Object value) throws RuntimeCamelException;
+
}
+
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,44 @@
+/**
+ * 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;
+
+/**
+ * An exception caused when an invalid property name is used on an object
+ */
+public class InvalidPropertyException extends RuntimeCamelException {
+ private static final long serialVersionUID = 3450859794325167954L;
+ private final transient Object owner;
+ private final String propertyName;
+
+ public InvalidPropertyException(Object owner, String propertyName) {
+ this(owner, propertyName, owner != null ? owner.getClass() : Object.class);
+ }
+
+ public InvalidPropertyException(Object owner, String propertyName, Class<?> type) {
+ super("No '" + propertyName + "' property available on type: " + type.getName() + " in: " + owner);
+ this.owner = owner;
+ this.propertyName = propertyName;
+ }
+
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ public Object getOwner() {
+ return owner;
+ }
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/InvalidPropertyException.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaComponent.java?rev=1470840&r1=1470839&r2=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaComponent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaComponent.java Tue Apr 23 08:00:07 2013
@@ -24,6 +24,7 @@ import java.util.concurrent.LinkedBlocki
import org.apache.camel.Endpoint;
import org.apache.camel.Exchange;
import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.impl.UriEndpointComponent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,13 +34,17 @@ import org.slf4j.LoggerFactory;
*
* @version
*/
-public class SedaComponent extends DefaultComponent {
+public class SedaComponent extends UriEndpointComponent {
protected final transient Logger log = LoggerFactory.getLogger(getClass());
protected final int maxConcurrentConsumers = 500;
protected int queueSize;
protected int defaultConcurrentConsumers = 1;
private final Map<String, QueueReference> queues = new HashMap<String, QueueReference>();
-
+
+ public SedaComponent() {
+ super(SedaEndpoint.class);
+ }
+
public void setQueueSize(int size) {
queueSize = size;
}
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,43 @@
+/**
+ *
+ * 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.lang.reflect.AccessibleObject;
+
+/**
+ * An implementation of {@link ParameterConfiguration} which comes from a field or setter method
+ * which has access to its underlying annotations to be able to expose additional validation
+ * and conversion metadata for the parameter via annotations
+ */
+public class AnnotatedParameterConfiguration extends ParameterConfiguration {
+ private final AccessibleObject accessibleObject;
+
+ public AnnotatedParameterConfiguration(String name, Class<?> type, AccessibleObject accessibleObject) {
+ super(name, type);
+ this.accessibleObject = accessibleObject;
+ }
+
+ public AccessibleObject getAccessibleObject() {
+ return accessibleObject;
+ }
+
+ @Override
+ public String toString() {
+ return "AnnotatedParameterConfiguration[" + getName() + " on " + accessibleObject + "]";
+ }
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/AnnotatedParameterConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,176 @@
+/**
+ *
+ * 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.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.camel.Component;
+import org.apache.camel.ComponentConfiguration;
+import org.apache.camel.Endpoint;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+import org.apache.camel.util.UnsafeUriCharactersEncoder;
+
+/**
+ * Useful base class for implementations of {@link ComponentConfiguration}
+ */
+public abstract class ComponentConfigurationSupport implements ComponentConfiguration {
+ protected final Component component;
+ private Map<String, Object> propertyValues = new HashMap<String, Object>();
+ private String baseUri;
+
+ public ComponentConfigurationSupport(Component component) {
+ this.component = component;
+ }
+
+ @Override
+ public Map<String, Object> getParameters() {
+ return Collections.unmodifiableMap(propertyValues);
+ }
+
+ @Override
+ public void setParameters(Map<String, Object> newValues) {
+ ObjectHelper.notNull(newValues, "propertyValues");
+ this.propertyValues.clear();
+ // lets validate each property as we set it
+ Set<Map.Entry<String, Object>> entries = newValues.entrySet();
+ for (Map.Entry<String, Object> entry : entries) {
+ setParameter(entry.getKey(), entry.getValue());
+ }
+ }
+
+ @Override
+ public Object getParameter(String name) {
+ validatePropertyName(name);
+ return propertyValues.get(name);
+ }
+
+ @Override
+ public void setParameter(String name, Object value) {
+ Object convertedValue = validatePropertyValue(name, value);
+ propertyValues.put(name, convertedValue);
+ }
+
+ /**
+ * Returns the base URI without any scheme or URI query parameters (property values)
+ */
+ @Override
+ public String getBaseUri() {
+ return baseUri;
+ }
+
+ @Override
+ public void setBaseUri(String baseUri) {
+ this.baseUri = baseUri;
+ }
+
+ @Override
+ public Endpoint createEndpoint() throws Exception {
+ String uri = getUriString();
+ return component.createEndpoint(uri);
+ }
+
+ /**
+ * Configures the properties on the given endpoint
+ */
+ @Override
+ public void configureEndpoint(Endpoint endpoint) {
+ Map<String, Object> map = getParameters();
+ if (map != null) {
+ Set<Map.Entry<String, Object>> entries = map.entrySet();
+ for (Map.Entry<String, Object> entry : entries) {
+ setEndpointParameter(endpoint, entry.getKey(), entry.getValue());
+ }
+ }
+ // TODO validate all the values are valid (e.g. mandatory)
+ }
+
+ @Override
+ public String getUriString() {
+ List<String> queryParams = new ArrayList<String>();
+ for (Map.Entry<String, Object> entry : getParameters().entrySet()) {
+ String key = entry.getKey();
+ Object value = entry.getValue();
+ // convert to "param=value" format here, order will be preserved
+ if (value instanceof List) {
+ for (Object item : (List<?>)value) {
+ queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(item.toString()));
+ }
+ } else {
+ queryParams.add(key + "=" + UnsafeUriCharactersEncoder.encode(value.toString()));
+ }
+ }
+ Collections.sort(queryParams);
+ StringBuilder builder = new StringBuilder();
+ String base = getBaseUri();
+ if (base != null) {
+ builder.append(base);
+ }
+ String separator = "?";
+ for (String entry : queryParams) {
+ builder.append(separator);
+ builder.append(entry);
+ separator = "&";
+ }
+ return builder.toString();
+ }
+
+ @Override
+ public void setUriString(String uri) throws URISyntaxException {
+ String path = uri;
+ int idx = path.indexOf('?');
+ Map<String, Object> newParameters = Collections.EMPTY_MAP;
+ if (idx >= 0) {
+ path = path.substring(0, idx);
+ String query = uri.substring(idx + 1);
+ newParameters = URISupport.parseQuery(query, true);
+ }
+ setBaseUri(path);
+ setParameters(newParameters);
+ }
+
+ @Override
+ public ParameterConfiguration getParameterConfiguration(String name) {
+ return getParameterConfigurationMap().get(name);
+ }
+
+ /**
+ * Allow implementations to validate whether a property name is valid
+ * and either throw an exception or log a warning of an unknown property being used
+ */
+ protected void validatePropertyName(String name) {
+ }
+
+ /**
+ * Allow implementations to validate whether a property name is valid
+ * and either throw an exception or log a warning of an unknown property being used
+ * and to convert the given value to the correct type before updating the value.
+ */
+ protected Object validatePropertyValue(String name, Object value) {
+ validatePropertyName(name);
+ return value;
+ }
+
+
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ComponentConfigurationSupport.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java?rev=1470840&r1=1470839&r2=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponent.java Tue Apr 23 08:00:07 2013
@@ -23,6 +23,7 @@ import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
+import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Endpoint;
import org.apache.camel.EndpointConfiguration;
import org.apache.camel.ResolveEndpointFailedException;
@@ -138,6 +139,11 @@ public abstract class DefaultComponent e
return endpoint;
}
+ @Override
+ public ComponentConfiguration createComponentConfiguration() {
+ return new DefaultComponentConfiguration(this);
+ }
+
public EndpointConfiguration createConfiguration(String uri) throws Exception {
MappedEndpointConfiguration config = new MappedEndpointConfiguration(getCamelContext());
config.setURI(new URI(uri));
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,84 @@
+/**
+ *
+ * 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.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.camel.Component;
+import org.apache.camel.Endpoint;
+import org.apache.camel.InvalidPropertyException;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.util.IntrospectionSupport;
+
+/**
+ * Default implementation for components which do not inherit from {@link UriEndpointComponent} and
+ * do not have Endpoint classes annotated with {@link org.apache.camel.spi.UriEndpoint}
+ */
+public class DefaultComponentConfiguration extends ComponentConfigurationSupport {
+ public DefaultComponentConfiguration(Component component) {
+ super(component);
+ }
+
+ @Override
+ public Object getEndpointParameter(Endpoint endpoint, String name) throws RuntimeCamelException {
+ try {
+ return IntrospectionSupport.getProperty(endpoint, name);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to get property " + name + " on endpoint " + endpoint + " due to " + e, e);
+ }
+ }
+
+ @Override
+ public void setEndpointParameter(Endpoint endpoint, String name, Object value)
+ throws RuntimeCamelException {
+ boolean answer = false;
+ try {
+ answer = IntrospectionSupport.setProperty(endpoint, name, value);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to set property " + name + " with value " + value + " on endpoint " + endpoint
+ + " due to " + e, e);
+ }
+ if (!answer) {
+ throw new InvalidPropertyException(endpoint, name);
+ }
+ }
+
+ /**
+ * Since we have no parameter metadata lets just return parameter configurations for each parameter we
+ * have right now.
+ *
+ * @return configurations for each current property value
+ */
+ @Override
+ public SortedMap<String, ParameterConfiguration> getParameterConfigurationMap() {
+ SortedMap<String, ParameterConfiguration> answer = new TreeMap<String, ParameterConfiguration>();
+ Set<Map.Entry<String, Object>> entries = getParameters().entrySet();
+ for (Map.Entry<String, Object> entry : entries) {
+ String name = entry.getKey();
+ Object value = entry.getValue();
+ Class<?> type = (value != null) ? value.getClass() : String.class;
+ answer.put(name, new ParameterConfiguration(name, type));
+ }
+ return answer;
+ }
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultComponentConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,64 @@
+/**
+ *
+ * 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.lang.reflect.Field;
+
+import org.apache.camel.spi.UriParam;
+
+/**
+ * Represents the configuration of a URI query parameter value to allow type conversion
+ * and better validation of the configuration of URIs and Endpoints
+ */
+public class ParameterConfiguration {
+ private final String name;
+ private final Class<?> parameterType;
+
+ public ParameterConfiguration(String name, Class<?> parameterType) {
+ this.name = name;
+ this.parameterType = parameterType;
+ }
+
+ @Override
+ public String toString() {
+ return "ParameterConfiguration[" + name + " on " + parameterType + "]";
+ }
+
+ /**
+ * Returns the name of the parameter value
+ *
+ * @return
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the type of the parameter value
+ */
+ public Class<?> getParameterType() {
+ return parameterType;
+ }
+
+ /**
+ * Factory method to create a new ParameterConfiguration from a field
+ */
+ public static ParameterConfiguration newInstance(String name, Field field, UriParam uriParam) {
+ return new AnnotatedParameterConfiguration(name, field.getType(), field);
+ }
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ParameterConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,158 @@
+/**
+ *
+ * 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.Collections;
+import java.util.SortedMap;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Component;
+import org.apache.camel.Endpoint;
+import org.apache.camel.InvalidPropertyException;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.util.IntrospectionSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements {@link org.apache.camel.EndpointConfiguration} for Endpoint implementations
+ * which are annotated with {@link UriEndpoint}
+ * to use the {@link org.apache.camel.spi.UriParam} and {@link org.apache.camel.spi.UriParams} annotations
+ * to denote its parameters which can be specified via URI query parameters.
+ */
+public class UriComponentConfiguration extends ComponentConfigurationSupport {
+ private static final transient Logger LOG = LoggerFactory.getLogger(UriComponentConfiguration.class);
+
+ private final Class<? extends Endpoint> endpointClass;
+ private final SortedMap<String, ParameterConfiguration> parameterConfigurationMap;
+ private boolean strictOnParameterNames = true;
+
+ public UriComponentConfiguration(Component component, Class<? extends Endpoint> endpointClass,
+ SortedMap<String, ParameterConfiguration> parameterConfigurationMap) {
+ super(component);
+ this.endpointClass = endpointClass;
+ this.parameterConfigurationMap = Collections.unmodifiableSortedMap(parameterConfigurationMap);
+ }
+
+ public UriComponentConfiguration(Component component, Class<? extends Endpoint> endpointClass) {
+ this(component, endpointClass, UriEndpointComponent.createParameterConfigurationMap(endpointClass));
+ }
+
+ public UriComponentConfiguration(UriEndpointComponent component) {
+ this(component, component.getEndpointClass(), component.getParameterConfigurationMap());
+ }
+
+ @Override
+ public Object getEndpointParameter(Endpoint endpoint, String name) throws RuntimeCamelException {
+ ParameterConfiguration config = getParameterConfiguration(name);
+
+ // lets try get the property regardless of if this maps to a valid property name
+ // then if the introspection fails we will get a valid error otherwise
+ // lets raise a warning afterwards that we should update the metadata on the endpoint class
+ Object answer = null;
+ try {
+ answer = IntrospectionSupport.getProperty(endpoint, name);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to get property '" + name + "' on " + endpoint + " due " + e.getMessage(), e);
+ }
+ if (config == null) {
+ unknownPropertyName(name);
+ }
+ return answer;
+ }
+
+ @Override
+ public void setEndpointParameter(Endpoint endpoint, String name, Object value)
+ throws RuntimeCamelException {
+ ParameterConfiguration config = getParameterConfiguration(name);
+
+ // lets try set the property regardless of if this maps to a valid property name
+ // then if the injection fails we will get a valid error otherwise
+ // lets raise a warning afterwards that we should update the metadata on the endpoint class
+ try {
+ IntrospectionSupport.setProperty(endpoint, name, value);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to set property '" + name + "' on " + endpoint + " to value " + value + " due "
+ + e.getMessage(), e);
+ }
+ if (config == null) {
+ unknownPropertyName(name);
+ }
+ }
+
+ public CamelContext getCamelContext() {
+ return component.getCamelContext();
+ }
+
+ public Class<? extends Endpoint> getEndpointClass() {
+ return endpointClass;
+ }
+
+ public boolean isStrictOnParameterNames() {
+ return strictOnParameterNames;
+ }
+
+ /**
+ * Strict mode is enabled by default but if disabled then invalid parameter names
+ * will not result in exceptions but we will just log warnings about their use
+ *
+ * @param strictOnParameterNames whether to throw exceptions if invalid
+ * parameter names are used or not
+ */
+ public void setStrictOnParameterNames(boolean strictOnParameterNames) {
+ this.strictOnParameterNames = strictOnParameterNames;
+ }
+
+ @Override
+ public SortedMap<String, ParameterConfiguration> getParameterConfigurationMap() {
+ return parameterConfigurationMap;
+ }
+
+ @Override
+ protected void validatePropertyName(String name) {
+ ParameterConfiguration parameterConfiguration = getParameterConfiguration(name);
+ if (parameterConfiguration == null) {
+ unknownPropertyName(name);
+ }
+ }
+
+ @Override
+ protected Object validatePropertyValue(String name, Object value) {
+ ParameterConfiguration parameterConfiguration = getParameterConfiguration(name);
+ if (parameterConfiguration == null) {
+ unknownPropertyName(name);
+ return value;
+ } else {
+ Class<?> parameterType = parameterConfiguration.getParameterType();
+ return getCamelContext().getTypeConverter().convertTo(parameterType, value);
+ }
+ }
+
+ protected void unknownPropertyName(String name) {
+ if (isStrictOnParameterNames()) {
+ throw new InvalidPropertyException(this, name, endpointClass);
+ } else {
+ LOG.warn("Using parameter " + name + " on endpoint " + getEndpointClass().getName()
+ + " which does not have a @UriParam annotation! " +
+ "Please add the @UriParam annotation to the " + name + "field");
+ }
+ }
+
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriComponentConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,122 @@
+/**
+ *
+ * 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.lang.reflect.Field;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.ComponentConfiguration;
+import org.apache.camel.Endpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.ReflectionHelper;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A component implementation for endpoints which are annotated with UriEndpoint to describe
+ * their configurable parameters via annotations
+ */
+public abstract class UriEndpointComponent extends DefaultComponent {
+ private static final transient Logger LOG = LoggerFactory.getLogger(UriEndpointComponent.class);
+
+ private final Class<? extends Endpoint> endpointClass;
+ private SortedMap<String, ParameterConfiguration> parameterConfigurationMap;
+
+ public UriEndpointComponent(Class<? extends Endpoint> endpointClass) {
+ this.endpointClass = endpointClass;
+ }
+
+ public UriEndpointComponent(CamelContext context, Class<? extends Endpoint> endpointClass) {
+ super(context);
+ this.endpointClass = endpointClass;
+ }
+
+ @Override
+ public ComponentConfiguration createComponentConfiguration() {
+ return new UriComponentConfiguration(this);
+ }
+
+ /**
+ * Returns a newly created sorted map, indexed by name of all the parameter configurations
+ * of the given endpoint class using introspection for the various annotations like
+ * {@link org.apache.camel.spi.UriEndpoint}, {@link org.apache.camel.spi.UriParam}, {@link org.apache.camel.spi.UriParams}
+ */
+ public static SortedMap<String, ParameterConfiguration> createParameterConfigurationMap(
+ Class<? extends Endpoint> endpointClass) {
+ SortedMap<String, ParameterConfiguration> answer = new TreeMap<String, ParameterConfiguration>();
+ populateParameterConfigurationMap(answer, endpointClass, "");
+ return answer;
+ }
+
+ protected static void populateParameterConfigurationMap(
+ final SortedMap<String, ParameterConfiguration> parameterMap, Class<?> aClass,
+ final String prefix) {
+ ReflectionHelper.doWithFields(aClass, new ReflectionHelper.FieldCallback() {
+ @Override
+ public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
+ UriParam uriParam = field.getAnnotation(UriParam.class);
+ if (uriParam != null) {
+ String name = uriParam.name();
+ if (ObjectHelper.isEmpty(name)) {
+ name = field.getName();
+ }
+ String propertyName = prefix + name;
+
+ // is the parameter a nested configuration object
+ Class<?> fieldType = field.getType();
+ UriParams uriParams = fieldType.getAnnotation(UriParams.class);
+ if (uriParams != null) {
+ String nestedPrefix = uriParams.prefix();
+ if (nestedPrefix == null) {
+ nestedPrefix = "";
+ }
+ nestedPrefix = (prefix + nestedPrefix).trim();
+ populateParameterConfigurationMap(parameterMap, fieldType, nestedPrefix);
+ } else {
+ if (parameterMap.containsKey(propertyName)) {
+ LOG.warn(
+ "Duplicate property name " + propertyName + " defined on field " + field);
+ } else {
+ parameterMap.put(propertyName,
+ ParameterConfiguration.newInstance(propertyName, field, uriParam));
+ }
+ }
+ }
+ }
+ });
+ }
+
+ public Class<? extends Endpoint> getEndpointClass() {
+ return endpointClass;
+ }
+
+ /**
+ * Returns the sorted map of all the URI query parameter names to their {@link ParameterConfiguration} objects
+ */
+ public SortedMap<String, ParameterConfiguration> getParameterConfigurationMap() {
+ if (parameterConfigurationMap == null) {
+ parameterConfigurationMap = createParameterConfigurationMap(getEndpointClass());
+ }
+ return new TreeMap<String, ParameterConfiguration>(parameterConfigurationMap);
+ }
+
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointComponent.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java (added)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,149 @@
+/**
+ *
+ * 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.net.URI;
+import java.net.URISyntaxException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.EndpointConfiguration;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.util.IntrospectionSupport;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Implements {@link EndpointConfiguration} for Endpoint implementations
+ * which are annotated with {@link UriEndpoint} to use the {@link UriParam} and {@link UriParams} annotations
+ * to denote its parameters which can be specified via URI query parameters.
+ */
+public class UriEndpointConfiguration implements EndpointConfiguration {
+ private static final transient Logger LOG = LoggerFactory.getLogger(UriEndpointConfiguration.class);
+
+ private final CamelContext camelContext;
+ private final Endpoint endpoint;
+ private String uriText;
+ private URI uri;
+ private SortedMap<String, ParameterConfiguration> propertyMap;
+
+ public UriEndpointConfiguration(CamelContext camelContext, Endpoint endpoint, String uriText) {
+ this.camelContext = camelContext;
+ this.endpoint = endpoint;
+ this.uriText = uriText;
+ }
+
+ @Override
+ public URI getURI() {
+ if (uri == null) {
+ // lazily create the URI which may fail as not all camel uriText are valid URI text
+ try {
+ uri = new URI(uriText);
+ } catch (URISyntaxException e) {
+ throw new RuntimeCamelException(e);
+ }
+ }
+ return uri;
+ }
+
+ public void setURI(URI uri) {
+ this.uriText = null;
+ this.uri = uri;
+ }
+
+ @Override
+ public <T> T getParameter(String name) throws RuntimeCamelException {
+ ParameterConfiguration config = getPropertyConfiguration(name);
+
+ // lets try get the property regardless of if this maps to a valid property name
+ // then if the introspection fails we will get a valid error otherwise
+ // lets raise a warning afterwards that we should update the metadata on the endpoint class
+ T answer;
+ try {
+ answer = (T)IntrospectionSupport.getProperty(endpoint, name);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to get property '" + name + "' on " + endpoint + " due " + e.getMessage(), e);
+ }
+ if (config == null) {
+ warnMissingUriParamOnProperty(name);
+ }
+ return answer;
+ }
+
+ protected void warnMissingUriParamOnProperty(String name) {
+ LOG.warn("Using property " + name + " on endpoint " + getEndpointClass().getName()
+ + " which does not have a @UriParam annotation! " +
+ "Please add the @UriParam annotation to the " + name + "field");
+ }
+
+ @Override
+ public <T> void setParameter(String name, T value) throws RuntimeCamelException {
+ ParameterConfiguration config = getPropertyConfiguration(name);
+
+ // lets try set the property regardless of if this maps to a valid property name
+ // then if the injection fails we will get a valid error otherwise
+ // lets raise a warning afterwards that we should update the metadata on the endpoint class
+ try {
+ IntrospectionSupport.setProperty(endpoint, name, value);
+ } catch (Exception e) {
+ throw new RuntimeCamelException(
+ "Failed to set property '" + name + "' on " + endpoint + " to value " + value + " due "
+ + e.getMessage(), e);
+ }
+ if (config == null) {
+ warnMissingUriParamOnProperty(name);
+ }
+ }
+
+ @Override
+ public String toUriString(UriFormat format) {
+ // TODO
+ return null;
+ }
+
+ public CamelContext getCamelContext() {
+ return camelContext;
+ }
+
+ public Class<? extends Endpoint> getEndpointClass() {
+ return endpoint.getClass();
+ }
+
+ /**
+ * Returns the property configuration for the given property name or null if it does not exist
+ */
+ public ParameterConfiguration getPropertyConfiguration(String name) {
+ return getPropertyConfigurationMap().get(name);
+ }
+
+ /**
+ * Returns the sorted map of all the property names to their {@link ParameterConfiguration} objects
+ */
+ public SortedMap<String, ParameterConfiguration> getPropertyConfigurationMap() {
+ if (propertyMap == null) {
+ propertyMap = UriEndpointComponent.createParameterConfigurationMap(getEndpointClass());
+ }
+ return new TreeMap<String, ParameterConfiguration>(propertyMap);
+ }
+
+}
Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/UriEndpointConfiguration.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java?rev=1470840&view=auto
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java (added)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java Tue Apr 23 08:00:07 2013
@@ -0,0 +1,421 @@
+/**
+ *
+ * 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 transient 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) {
+ System.out.println("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) {
+ System.out.println("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());
+
+ System.out.println("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) {
+ System.out.println("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) {
+ System.out.println("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());
+
+ System.out.println(component + " has has configuration properties " + 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) {
+ System.out.println("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) {
+ System.out.println("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;
+ }
+ }
+}
Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ComponentConfigurationTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java?rev=1470840&r1=1470839&r2=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/ConfigurationHelperTest.java Tue Apr 23 08:00:07 2013
@@ -22,6 +22,7 @@ import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
+import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Endpoint;
import org.apache.camel.EndpointConfiguration;
import org.apache.camel.URIField;
@@ -35,6 +36,9 @@ import static org.junit.Assert.assertEqu
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+/**
+ * @see ComponentConfigurationTest for tests using the {@link ComponentConfiguration} mechanism
+ */
public class ConfigurationHelperTest {
private static final transient Logger LOG = LoggerFactory.getLogger(ConfigurationHelperTest.class);
@@ -231,6 +235,11 @@ public class ConfigurationHelperTest {
}
@Override
+ public ComponentConfiguration createComponentConfiguration() {
+ return null;
+ }
+
+ @Override
public EndpointConfiguration createConfiguration(String uri) throws Exception {
if (uri.equals(URIDUMP_SCHEME)) {
return new UriDumpConfiguration(getCamelContext());
Modified: camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java?rev=1470840&r1=1470839&r2=1470840&view=diff
==============================================================================
--- camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java (original)
+++ camel/trunk/camel-core/src/test/java/org/apache/camel/impl/EndpointConfigurationTest.java Tue Apr 23 08:00:07 2013
@@ -18,6 +18,7 @@ package org.apache.camel.impl;
import org.apache.camel.CamelContext;
import org.apache.camel.Component;
+import org.apache.camel.ComponentConfiguration;
import org.apache.camel.Endpoint;
import org.apache.camel.EndpointConfiguration;
import org.junit.AfterClass;
@@ -88,6 +89,11 @@ public class EndpointConfigurationTest {
}
@Override
+ public ComponentConfiguration createComponentConfiguration() {
+ return null;
+ }
+
+ @Override
public EndpointConfiguration createConfiguration(String uri) throws Exception {
return new MappedEndpointConfiguration(getCamelContext());
}