/** * 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.cometd; import java.net.URI; import java.net.URISyntaxException; import java.util.Map; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.impl.DefaultEndpoint; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.spi.UriPath; import org.apache.camel.util.ObjectHelper; /** * The cometd component is a transport for working with the Jetty implementation of the cometd/bayeux protocol. * * Using this component in combination with the dojo toolkit library it's possible to push Camel messages directly * into the browser using an AJAX based mechanism. */ @UriEndpoint(firstVersion = "2.0.0", scheme = "cometd,cometds", title = "CometD", syntax = "cometd:host:port/channelName", consumerClass = CometdConsumer.class, label = "websocket") public class CometdEndpoint extends DefaultEndpoint { private CometdComponent component; private URI uri; @UriPath(description = "Hostname") @Metadata(required = "true") private String host; @UriPath(description = "Host port number") @Metadata(required = "true") private int port; @UriPath(description = "The channelName represents a topic that can be subscribed to by the Camel endpoints.") @Metadata(required = "true") private String channelName; @UriParam private String baseResource; @UriParam(defaultValue = "240000") private int timeout = 240000; @UriParam private int interval; @UriParam(defaultValue = "30000") private int maxInterval = 30000; @UriParam(defaultValue = "1500") private int multiFrameInterval = 1500; @UriParam(defaultValue = "true") private boolean jsonCommented = true; @UriParam(label = "consumer") private boolean sessionHeadersEnabled; @UriParam(defaultValue = "1", enums = "0,1,2") private int logLevel = 1; @UriParam private boolean crossOriginFilterOn; @UriParam(defaultValue = "*") private String allowedOrigins; @UriParam private String filterPath; @UriParam(label = "producer") private boolean disconnectLocalSession; public CometdEndpoint(CometdComponent component, String uri, String remaining, Map<String, Object> parameters) { super(uri, component); this.component = component; try { this.uri = new URI(uri); this.host = this.uri.getHost(); this.port = this.uri.getPort(); this.channelName = remaining; } catch (URISyntaxException e) { throw new IllegalArgumentException(e); } } public Producer createProducer() throws Exception { ObjectHelper.notNull(component, "component"); CometdProducer producer = new CometdProducer(this); return producer; } public Consumer createConsumer(Processor processor) throws Exception { ObjectHelper.notNull(component, "component"); CometdConsumer consumer = new CometdConsumer(this, processor); configureConsumer(consumer); return consumer; } public void connect(CometdProducerConsumer prodcons) throws Exception { component.connect(prodcons); } public void disconnect(CometdProducerConsumer prodcons) throws Exception { component.disconnect(prodcons); } public CometdComponent getComponent() { return component; } public boolean isSingleton() { return true; } public String getPath() { return uri.getPath(); } public int getPort() { if (uri.getPort() == -1) { if ("cometds".equals(getProtocol())) { return 443; } else { return 80; } } return uri.getPort(); } public String getProtocol() { return uri.getScheme(); } public URI getUri() { return uri; } public String getBaseResource() { return baseResource; } /** * The root directory for the web resources or classpath. Use the protocol file: or classpath: depending * if you want that the component loads the resource from file system or classpath. * Classpath is required for OSGI deployment where the resources are packaged in the jar */ public void setBaseResource(String baseResource) { this.baseResource = baseResource; } public int getTimeout() { return timeout; } /** * The server side poll timeout in milliseconds. This is how long the server will hold a reconnect request before responding. */ public void setTimeout(int timeout) { this.timeout = timeout; } public int getInterval() { return interval; } /** * The client side poll timeout in milliseconds. How long a client will wait between reconnects */ public void setInterval(int interval) { this.interval = interval; } public int getMaxInterval() { return maxInterval; } /** * The max client side poll timeout in milliseconds. A client will be removed if a connection is not received in this time. */ public void setMaxInterval(int maxInterval) { this.maxInterval = maxInterval; } public int getMultiFrameInterval() { return multiFrameInterval; } /** * The client side poll timeout, if multiple connections are detected from the same browser. */ public void setMultiFrameInterval(int multiFrameInterval) { this.multiFrameInterval = multiFrameInterval; } public boolean isJsonCommented() { return jsonCommented; } /** * If true, the server will accept JSON wrapped in a comment and will generate JSON wrapped in a comment. This is a defence against Ajax Hijacking. */ public void setJsonCommented(boolean commented) { jsonCommented = commented; } /** * Whether to include the server session headers in the Camel message when creating a Camel Message for incoming requests. */ public void setSessionHeadersEnabled(boolean enable) { this.sessionHeadersEnabled = enable; } public boolean isSessionHeadersEnabled() { return sessionHeadersEnabled; } public int getLogLevel() { return logLevel; } /** * Logging level. 0=none, 1=info, 2=debug. */ public void setLogLevel(int logLevel) { this.logLevel = logLevel; } public String getAllowedOrigins() { return allowedOrigins; } /** * The origins domain that support to cross, if the crosssOriginFilterOn is true */ public void setAllowedOrigins(String allowedOrigins) { this.allowedOrigins = allowedOrigins; } public boolean isCrossOriginFilterOn() { return crossOriginFilterOn; } /** * If true, the server will support for cross-domain filtering */ public void setCrossOriginFilterOn(boolean crossOriginFilterOn) { this.crossOriginFilterOn = crossOriginFilterOn; } public String getFilterPath() { return filterPath; } /** * The filterPath will be used by the CrossOriginFilter, if the crosssOriginFilterOn is true */ public void setFilterPath(String filterPath) { this.filterPath = filterPath; } public boolean isDisconnectLocalSession() { return disconnectLocalSession; } /** * Whether to disconnect local sessions after publishing a message to its channel. * Disconnecting local session is needed as they are not swept by default by CometD, and therefore you can run out of memory. */ public void setDisconnectLocalSession(boolean disconnectLocalSession) { this.disconnectLocalSession = disconnectLocalSession; } }