blob: 545591b9bd7bad880f9c3fdc225f0a6ed3df1212 [file] [log] [blame]
/**
* 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.netty.http;
import java.util.Map;
import org.apache.camel.AsyncEndpoint;
import org.apache.camel.Consumer;
import org.apache.camel.Exchange;
import org.apache.camel.Message;
import org.apache.camel.PollingConsumer;
import org.apache.camel.Processor;
import org.apache.camel.Producer;
import org.apache.camel.component.netty.NettyConfiguration;
import org.apache.camel.component.netty.NettyEndpoint;
import org.apache.camel.impl.SynchronousDelegateProducer;
import org.apache.camel.spi.HeaderFilterStrategy;
import org.apache.camel.spi.HeaderFilterStrategyAware;
import org.apache.camel.spi.UriEndpoint;
import org.apache.camel.spi.UriParam;
import org.apache.camel.util.ObjectHelper;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Netty HTTP server and client using the Netty 3.x library.
*/
@UriEndpoint(scheme = "netty-http", extendsScheme = "netty", title = "Netty HTTP",
syntax = "netty-http:protocol:host:port/path", consumerClass = NettyHttpConsumer.class, label = "http", lenientProperties = true,
excludeProperties = "textline,delimiter,autoAppendDelimiter,decoderMaxLineLength,encoding,allowDefaultCodec,udpConnectionlessSending,networkInterface"
+ ",clientMode,reconnect,reconnectInterval,broadcast")
public class NettyHttpEndpoint extends NettyEndpoint implements AsyncEndpoint, HeaderFilterStrategyAware {
private static final Logger LOG = LoggerFactory.getLogger(NettyHttpEndpoint.class);
@UriParam
private NettyHttpConfiguration configuration;
@UriParam(label = "advanced", name = "configuration", javaType = "org.apache.camel.component.netty.http.NettyHttpConfiguration",
description = "To use a custom configured NettyHttpConfiguration for configuring this endpoint.")
private Object httpConfiguration; // to include in component docs as NettyHttpConfiguration is a @UriParams class
@UriParam(label = "advanced")
private NettyHttpBinding nettyHttpBinding;
@UriParam(label = "advanced")
private HeaderFilterStrategy headerFilterStrategy;
@UriParam(label = "consumer,advanced")
private boolean traceEnabled;
@UriParam(label = "consumer,advanced")
private String httpMethodRestrict;
@UriParam(label = "consumer,advanced")
private NettySharedHttpServer nettySharedHttpServer;
@UriParam(label = "consumer,security")
private NettyHttpSecurityConfiguration securityConfiguration;
@UriParam(label = "consumer,security", prefix = "securityConfiguration.", multiValue = true)
private Map<String, Object> securityOptions; // to include in component docs
public NettyHttpEndpoint(String endpointUri, NettyHttpComponent component, NettyConfiguration configuration) {
super(endpointUri, component, configuration);
}
@Override
public NettyHttpComponent getComponent() {
return (NettyHttpComponent) super.getComponent();
}
@Override
public Consumer createConsumer(Processor processor) throws Exception {
NettyHttpConsumer answer = new NettyHttpConsumer(this, processor, getConfiguration());
configureConsumer(answer);
if (nettySharedHttpServer != null) {
answer.setNettyServerBootstrapFactory(nettySharedHttpServer.getServerBootstrapFactory());
LOG.info("NettyHttpConsumer: {} is using NettySharedHttpServer on port: {}", answer, nettySharedHttpServer.getPort());
} else {
// reuse pipeline factory for the same address
HttpServerBootstrapFactory factory = getComponent().getOrCreateHttpNettyServerBootstrapFactory(answer);
// force using our server bootstrap factory
answer.setNettyServerBootstrapFactory(factory);
LOG.debug("Created NettyHttpConsumer: {} using HttpServerBootstrapFactory: {}", answer, factory);
}
return answer;
}
@Override
public Producer createProducer() throws Exception {
Producer answer = new NettyHttpProducer(this, getConfiguration());
if (isSynchronous()) {
return new SynchronousDelegateProducer(answer);
} else {
return answer;
}
}
@Override
public PollingConsumer createPollingConsumer() throws Exception {
throw new UnsupportedOperationException("This component does not support polling consumer");
}
@Override
public Exchange createExchange(ChannelHandlerContext ctx, MessageEvent messageEvent) throws Exception {
Exchange exchange = createExchange();
// use the http binding
HttpRequest request = (HttpRequest) messageEvent.getMessage();
Message in = getNettyHttpBinding().toCamelMessage(request, exchange, getConfiguration());
exchange.setIn(in);
// setup the common message headers
updateMessageHeader(in, ctx, messageEvent);
// honor the character encoding
String contentType = in.getHeader(Exchange.CONTENT_TYPE, String.class);
String charset = NettyHttpHelper.getCharsetFromContentType(contentType);
if (charset != null) {
exchange.setProperty(Exchange.CHARSET_NAME, charset);
in.setHeader(Exchange.HTTP_CHARACTER_ENCODING, charset);
}
return exchange;
}
@Override
public boolean isLenientProperties() {
// true to allow dynamic URI options to be configured and passed to external system for eg. the HttpProducer
return true;
}
@Override
public void setConfiguration(NettyConfiguration configuration) {
super.setConfiguration(configuration);
this.configuration = (NettyHttpConfiguration) configuration;
}
@Override
public NettyHttpConfiguration getConfiguration() {
return (NettyHttpConfiguration) super.getConfiguration();
}
public NettyHttpBinding getNettyHttpBinding() {
return nettyHttpBinding;
}
/**
* To use a custom org.apache.camel.component.netty.http.NettyHttpBinding for binding to/from Netty and Camel Message API.
*/
public void setNettyHttpBinding(NettyHttpBinding nettyHttpBinding) {
this.nettyHttpBinding = nettyHttpBinding;
}
public HeaderFilterStrategy getHeaderFilterStrategy() {
return headerFilterStrategy;
}
/**
* To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter headers.
*/
public void setHeaderFilterStrategy(HeaderFilterStrategy headerFilterStrategy) {
this.headerFilterStrategy = headerFilterStrategy;
getNettyHttpBinding().setHeaderFilterStrategy(headerFilterStrategy);
}
public boolean isTraceEnabled() {
return traceEnabled;
}
/**
* Specifies whether to enable HTTP TRACE for this Netty HTTP consumer. By default TRACE is turned off.
*/
public void setTraceEnabled(boolean traceEnabled) {
this.traceEnabled = traceEnabled;
}
public String getHttpMethodRestrict() {
return httpMethodRestrict;
}
/**
* To disable HTTP methods on the Netty HTTP consumer. You can specify multiple separated by comma.
*/
public void setHttpMethodRestrict(String httpMethodRestrict) {
this.httpMethodRestrict = httpMethodRestrict;
}
public NettySharedHttpServer getNettySharedHttpServer() {
return nettySharedHttpServer;
}
/**
* To use a shared Netty HTTP server. See Netty HTTP Server Example for more details.
*/
public void setNettySharedHttpServer(NettySharedHttpServer nettySharedHttpServer) {
this.nettySharedHttpServer = nettySharedHttpServer;
}
public NettyHttpSecurityConfiguration getSecurityConfiguration() {
return securityConfiguration;
}
/**
* Refers to a org.apache.camel.component.netty.http.NettyHttpSecurityConfiguration for configuring secure web resources.
*/
public void setSecurityConfiguration(NettyHttpSecurityConfiguration securityConfiguration) {
this.securityConfiguration = securityConfiguration;
}
public Map<String, Object> getSecurityOptions() {
return securityOptions;
}
/**
* To configure NettyHttpSecurityConfiguration using key/value pairs from the map
*/
public void setSecurityOptions(Map<String, Object> securityOptions) {
this.securityOptions = securityOptions;
}
@Override
protected void doStart() throws Exception {
super.doStart();
ObjectHelper.notNull(nettyHttpBinding, "nettyHttpBinding", this);
ObjectHelper.notNull(headerFilterStrategy, "headerFilterStrategy", this);
if (securityConfiguration != null) {
ObjectHelper.notEmpty(securityConfiguration.getRealm(), "realm", securityConfiguration);
ObjectHelper.notEmpty(securityConfiguration.getConstraint(), "restricted", securityConfiguration);
if (securityConfiguration.getSecurityAuthenticator() == null) {
// setup default JAAS authenticator if none was configured
JAASSecurityAuthenticator jaas = new JAASSecurityAuthenticator();
jaas.setName(securityConfiguration.getRealm());
LOG.info("No SecurityAuthenticator configured, using JAASSecurityAuthenticator as authenticator: {}", jaas);
securityConfiguration.setSecurityAuthenticator(jaas);
}
}
}
}