/**
* 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.routebox;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.camel.CamelContext;
import org.apache.camel.ProducerTemplate;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.routebox.strategy.RouteboxDispatchStrategy;
import org.apache.camel.impl.DefaultCamelContext;
import org.apache.camel.spi.Metadata;
import org.apache.camel.spi.Registry;
import org.apache.camel.spi.UriParam;
import org.apache.camel.spi.UriParams;
import org.apache.camel.spi.UriPath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@UriParams
public class RouteboxConfiguration {
private static final Logger LOG = LoggerFactory.getLogger(RouteboxConfiguration.class);
private URI uri;
private String authority;
@UriPath @Metadata(required = "true")
private String routeboxName;
@UriParam
private RouteboxDispatchStrategy dispatchStrategy;
@UriParam
private Map<String, String> dispatchMap;
@UriParam(defaultValue = "true")
private boolean forkContext = true;
@UriParam(label = "producer", defaultValue = "20000")
private long connectionTimeout = 20000;
@UriParam(label = "consumer", defaultValue = "1000")
private long pollInterval = 1000;
@UriParam(defaultValue = "direct", enums = "direct,seda")
private String innerProtocol = "direct";
@UriParam(label = "consumer", defaultValue = "20")
private int threads = 20;
@UriParam
private int queueSize;
@UriParam(label = "producer", defaultValue = "true")
private boolean sendToConsumer = true;
@UriParam(label = "advanced")
private CamelContext innerContext;
@UriParam(label = "advanced")
private Registry innerRegistry;
@UriParam(label = "advanced")
private ProducerTemplate innerProducerTemplate;
@UriParam(label = "advanced", javaType = "java.lang.String")
private List<RouteBuilder> routeBuilders = new ArrayList<RouteBuilder>();
public RouteboxConfiguration() {
}
public RouteboxConfiguration(URI uri) {
this();
this.uri = uri;
}
@SuppressWarnings("unchecked")
public void parseURI(URI uri, Map<String, Object> parameters, RouteboxComponent component) throws Exception {
String protocol = uri.getScheme();
if (!protocol.equalsIgnoreCase("routebox")) {
throw new IllegalArgumentException("Unrecognized protocol: " + protocol + " for uri: " + uri);
}
setUri(uri);
setAuthority(uri.getAuthority());
if (LOG.isTraceEnabled()) {
LOG.trace("Authority: {}", uri.getAuthority());
}
setRouteboxName(getAuthority());
if (parameters.containsKey("threads")) {
setThreads(Integer.valueOf((String) parameters.get("threads")));
}
if (parameters.containsKey("forkContext")) {
if (!(Boolean.valueOf((String) parameters.get("forkContext")))) {
setForkContext(false);
}
}
if (parameters.containsKey("innerProtocol")) {
setInnerProtocol((String) parameters.get("innerProtocol"));
if ((!innerProtocol.equalsIgnoreCase("seda")) && (!innerProtocol.equalsIgnoreCase("direct"))) {
throw new IllegalArgumentException("Unrecognized inner protocol: " + innerProtocol + " for uri: " + uri);
}
} else {
setInnerProtocol("direct");
}
if (parameters.containsKey("sendToConsumer")) {
if (!Boolean.valueOf((String) parameters.get("sendToConsumer"))) {
setSendToConsumer(false);
}
}
if (parameters.containsKey("connectionTimeout")) {
setConnectionTimeout(Long.parseLong((String) parameters.get("connectionTimeout")));
}
if (parameters.containsKey("pollInterval")) {
setConnectionTimeout(Long.parseLong((String) parameters.get("pollInterval")));
}
if (parameters.containsKey("routeBuilders")) {
routeBuilders = component.resolveAndRemoveReferenceParameter(parameters, "routeBuilders", List.class);
}
if (parameters.containsKey("innerRegistry")) {
innerRegistry = component.resolveAndRemoveReferenceParameter(parameters, "innerRegistry", Registry.class);
}
if (isForkContext()) {
if (innerRegistry != null) {
innerContext = component.resolveAndRemoveReferenceParameter(parameters, "innerContext", CamelContext.class, new DefaultCamelContext(innerRegistry));
} else {
innerContext = component.resolveAndRemoveReferenceParameter(parameters, "innerContext", CamelContext.class, new DefaultCamelContext());
}
} else {
innerContext = component.getCamelContext();
}
innerProducerTemplate = innerContext.createProducerTemplate();
setQueueSize(component.getAndRemoveParameter(parameters, "size", Integer.class, 0));
dispatchStrategy = component.resolveAndRemoveReferenceParameter(parameters, "dispatchStrategy", RouteboxDispatchStrategy.class, null);
dispatchMap = component.resolveAndRemoveReferenceParameter(parameters, "dispatchMap", HashMap.class, new HashMap<String, String>());
if (dispatchStrategy == null && dispatchMap == null) {
LOG.warn("No Routebox Dispatch Map or Strategy has been set. Routebox may not have more than one inner route.");
}
}
public URI getUri() {
return uri;
}
public void setUri(URI uri) {
this.uri = uri;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
public CamelContext getInnerContext() {
return innerContext;
}
/**
* A string representing a key in the Camel Registry matching an object value of the type org.apache.camel.CamelContext.
* If a CamelContext is not provided by the user a CamelContext is automatically created for deployment of inner routes.
*/
public void setInnerContext(CamelContext innerContext) {
this.innerContext = innerContext;
}
/**
* A string representing a key in the Camel Registry matching an object value of the type List<org.apache.camel.builder.RouteBuilder>.
* If the user does not supply an innerContext pre-primed with inner routes, the routeBuilders option must be provided as a non-empty
* list of RouteBuilders containing inner routes
*/
public void setRouteBuilders(List<RouteBuilder> routeBuilders) {
this.routeBuilders = routeBuilders;
}
public List<RouteBuilder> getRouteBuilders() {
return routeBuilders;
}
/**
* Whether to fork and create a new inner CamelContext instead of reusing the same CamelContext.
*/
public void setForkContext(boolean forkContext) {
this.forkContext = forkContext;
}
public boolean isForkContext() {
return forkContext;
}
/**
* Number of threads to be used by the routebox to receive requests.
*/
public void setThreads(int threads) {
this.threads = threads;
}
public int getThreads() {
return threads;
}
/**
* Logical name for the routebox (eg like a queue name)
*/
public void setRouteboxName(String routeboxName) {
this.routeboxName = routeboxName;
}
public String getRouteboxName() {
return routeboxName;
}
/**
* To use a custom RouteboxDispatchStrategy which allows to use custom dispatching instead of the default.
*/
public void setDispatchStrategy(RouteboxDispatchStrategy dispatchStrategy) {
this.dispatchStrategy = dispatchStrategy;
}
public RouteboxDispatchStrategy getDispatchStrategy() {
return dispatchStrategy;
}
/**
* Timeout in millis used by the producer when sending a message.
*/
public void setConnectionTimeout(long connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
public long getConnectionTimeout() {
return connectionTimeout;
}
public long getPollInterval() {
return pollInterval;
}
/**
* The timeout used when polling from seda.
* When a timeout occurs, the consumer can check whether it is allowed to continue running.
* Setting a lower value allows the consumer to react more quickly upon shutdown.
*/
public void setPollInterval(long pollInterval) {
this.pollInterval = pollInterval;
}
/**
* Create a fixed size queue to receive requests.
*/
public void setQueueSize(int queueSize) {
this.queueSize = queueSize;
}
public int getQueueSize() {
return queueSize;
}
public void setInnerProducerTemplate(ProducerTemplate innerProducerTemplate) {
this.innerProducerTemplate = innerProducerTemplate;
}
/**
* The ProducerTemplate to use by the internal embeded CamelContext
*/
public ProducerTemplate getInnerProducerTemplate() {
return innerProducerTemplate;
}
/**
* The Protocol used internally by the Routebox component. Can be Direct or SEDA. The Routebox component currently offers protocols that are JVM bound.
*/
public void setInnerProtocol(String innerProtocol) {
this.innerProtocol = innerProtocol;
}
public String getInnerProtocol() {
return innerProtocol;
}
/**
* To use a custom registry for the internal embedded CamelContext.
*/
public void setInnerRegistry(Registry innerRegistry) {
this.innerRegistry = innerRegistry;
}
public Registry getInnerRegistry() {
return innerRegistry;
}
/**
* Dictates whether a Producer endpoint sends a request to an external routebox consumer.
* If the setting is false, the Producer creates an embedded inner context and processes requests internally.
*/
public void setSendToConsumer(boolean sendToConsumer) {
this.sendToConsumer = sendToConsumer;
}
public boolean isSendToConsumer() {
return sendToConsumer;
}
/**
* A string representing a key in the Camel Registry matching an object value of the type HashMap<String, String>.
* The HashMap key should contain strings that can be matched against the value set for the exchange header ROUTE_DISPATCH_KEY.
* The HashMap value should contain inner route consumer URI's to which requests should be directed.
*/
public void setDispatchMap(Map<String, String> dispatchMap) {
this.dispatchMap = dispatchMap;
}
public Map<String, String> getDispatchMap() {
return dispatchMap;
}
}