camel-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From aka...@apache.org
Subject svn commit: r988163 [1/2] - in /camel/trunk: components/ components/camel-sip/ components/camel-sip/src/ components/camel-sip/src/main/ components/camel-sip/src/main/java/ components/camel-sip/src/main/java/org/ components/camel-sip/src/main/java/org/a...
Date Mon, 23 Aug 2010 16:01:04 GMT
Author: akarpe
Date: Mon Aug 23 16:01:03 2010
New Revision: 988163

URL: http://svn.apache.org/viewvc?rev=988163&view=rev
Log:
Initial version of the Camel SIP protocol component supporting the SIP publish/subscribe handshake via a Presence Agent

Added:
    camel/trunk/components/camel-sip/
    camel/trunk/components/camel-sip/pom.xml   (with props)
    camel/trunk/components/camel-sip/src/
    camel/trunk/components/camel-sip/src/main/
    camel/trunk/components/camel-sip/src/main/java/
    camel/trunk/components/camel-sip/src/main/java/org/
    camel/trunk/components/camel-sip/src/main/java/org/apache/
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java   (with props)
    camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java   (with props)
    camel/trunk/components/camel-sip/src/main/resources/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/
    camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/sip
    camel/trunk/components/camel-sip/src/main/resources/log4j.properties   (with props)
    camel/trunk/components/camel-sip/src/test/
    camel/trunk/components/camel-sip/src/test/java/
    camel/trunk/components/camel-sip/src/test/java/org/
    camel/trunk/components/camel-sip/src/test/java/org/apache/
    camel/trunk/components/camel-sip/src/test/java/org/apache/camel/
    camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/
    camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/
    camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java   (with props)
    camel/trunk/components/camel-sip/src/test/resources/
    camel/trunk/components/camel-sip/src/test/resources/log4j.properties   (with props)
Modified:
    camel/trunk/components/pom.xml
    camel/trunk/parent/pom.xml

Added: camel/trunk/components/camel-sip/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/pom.xml?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/pom.xml (added)
+++ camel/trunk/components/camel-sip/pom.xml Mon Aug 23 16:01:03 2010
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>components</artifactId>
+    <version>2.5-SNAPSHOT</version>
+  </parent>
+  
+	<artifactId>camel-sip</artifactId>
+	<packaging>bundle</packaging>
+	<name>Camel :: SIP</name>
+	<description>Camel SIP protocol based communication component</description>
+
+	<properties>
+		<camel.osgi.export.pkg>
+			org.apache.camel.component.sip.*
+		</camel.osgi.export.pkg>
+	</properties>
+  
+	<repositories>
+		<repository>
+			<id>jboss</id>
+			<url>http://repository.jboss.org/nexus/content/groups/public/</url>
+			<snapshots>
+				<enabled>false</enabled>
+			</snapshots>
+		</repository>
+	</repositories>
+	
+  	<dependencies>
+	    <dependency>
+	      	<groupId>org.apache.camel</groupId>
+	      	<artifactId>camel-core</artifactId>
+	    </dependency>   
+            <dependency>
+	      	<groupId>javax.sip</groupId>
+	      	<artifactId>jain-sip-api</artifactId>
+	      	<version>${jain-api-version}</version>
+	    </dependency>
+	    <dependency>
+	      	<groupId>javax.sip</groupId>
+	      	<artifactId>jain-sip-ri</artifactId>
+	      	<version>${jain-sip-version}</version>
+	    </dependency>
+	    	       
+		<!-- testing -->
+		<dependency>
+			<groupId>org.apache.camel</groupId>
+			<artifactId>camel-test</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>junit</groupId>
+			<artifactId>junit</artifactId>
+			<scope>test</scope>
+		</dependency>
+
+		<!-- logging -->
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-api</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>org.slf4j</groupId>
+			<artifactId>slf4j-log4j12</artifactId>
+			<scope>test</scope>
+		</dependency>
+		<dependency>
+			<groupId>log4j</groupId>
+			<artifactId>log4j</artifactId>
+			<scope>test</scope>
+		</dependency>
+  	</dependencies>
+
+  <build>
+    <defaultGoal>install</defaultGoal>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-compiler-plugin</artifactId>
+        <configuration>
+          <source>1.5</source>
+          <target>1.5</target>
+        </configuration>
+      </plugin>      
+    </plugins>
+  </build>
+</project>

Propchange: camel/trunk/components/camel-sip/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,37 @@
+/**
+ * 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.sip;
+
+import java.net.URI;
+import java.util.Map;
+
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultComponent;
+
+public class SipComponent extends DefaultComponent {
+    private SipConfiguration config;
+
+    @Override
+    protected Endpoint createEndpoint(String uri, String remaining, Map<String, Object> parameters) throws Exception {
+        config = new SipConfiguration();
+        config.initialize(new URI(uri), parameters, this);
+        
+        SipEndpoint sipEndpoint = new SipEndpoint(remaining, this, config);
+        setProperties(sipEndpoint.getConfiguration(), parameters);
+        return sipEndpoint;
+    }
+}
\ No newline at end of file

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,759 @@
+/**
+ * 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.sip;
+
+import java.net.URI;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.Properties;
+
+import javax.sip.ClientTransaction;
+import javax.sip.Dialog;
+import javax.sip.InvalidArgumentException;
+import javax.sip.ListeningPoint;
+import javax.sip.SipFactory;
+import javax.sip.SipStack;
+import javax.sip.address.Address;
+import javax.sip.address.AddressFactory;
+import javax.sip.address.SipURI;
+import javax.sip.header.CSeqHeader;
+import javax.sip.header.CallIdHeader;
+import javax.sip.header.ContactHeader;
+import javax.sip.header.ContentTypeHeader;
+import javax.sip.header.EventHeader;
+import javax.sip.header.ExpiresHeader;
+import javax.sip.header.ExtensionHeader;
+import javax.sip.header.FromHeader;
+import javax.sip.header.HeaderFactory;
+import javax.sip.header.MaxForwardsHeader;
+import javax.sip.header.ToHeader;
+import javax.sip.header.ViaHeader;
+import javax.sip.message.MessageFactory;
+import javax.sip.message.Request;
+
+import org.apache.camel.util.ObjectHelper;
+import org.apache.camel.util.URISupport;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+@SuppressWarnings("unchecked")
+public class SipConfiguration {    
+    private static final transient Log LOG = LogFactory.getLog(SipConfiguration.class);
+    private static final String IMPLEMENTATION = "gov.nist";
+    private URI uri;
+    private Map<String, Object> parameters;
+    private SipComponent component;
+    private AddressFactory addressFactory;
+    private MessageFactory messageFactory;
+    private HeaderFactory headerFactory;
+    private SipStack sipStack;
+    private ListeningPoint listeningPoint;
+    private String protocol;
+    private SipURI sipUri;
+    private String stackName;
+    private String transport;
+    private int maxForwards;
+    private boolean consumer;
+    private String eventHeaderName;
+    private String eventId;
+    private int msgExpiration;
+    private String useRouterForAllUris;
+    private long receiveTimeoutMillis;
+    private String maxMessageSize;
+    private String cacheConnections;
+    private String contentType;
+    private String contentSubType;
+    private String automaticDialogSupport;
+    private String nistServerLog;
+    private String nistDebugLog;
+    private String nistTraceLevel;
+    private SipFactory sipFactory;
+    private String fromUser;
+    private String fromHost;
+    private int fromPort;
+    private String toUser;
+    private String toHost;
+    private int toPort;
+    private boolean presenceAgent;
+    
+    private FromHeader fromHeader;
+    private ToHeader toHeader;
+    private ArrayList<ViaHeader> viaHeaders;
+    private ContentTypeHeader contentTypeHeader;
+    private CallIdHeader callIdHeader;
+    private MaxForwardsHeader maxForwardsHeader;
+    private ContactHeader contactHeader;
+    private EventHeader eventHeader;
+    private ExtensionHeader extensionHeader;
+    private ExpiresHeader expiresHeader;
+    private ClientTransaction clientTransactionId;
+    private Dialog dialog;
+    
+    public SipConfiguration() {
+        sipFactory = SipFactory.getInstance();
+        sipFactory.setPathName(IMPLEMENTATION);
+        
+        setStackName("NAME_NOT_SET");
+        setTransport("tcp");
+        setMaxMessageSize("1048576");
+        setCacheConnections("false");
+        setAutomaticDialogSupport("off");
+        setContentType("text");
+        setContentSubType("plain");   
+        setReceiveTimeoutMillis(10000);
+        setConsumer(false);
+        setUseRouterForAllUris("false");
+        setMsgExpiration(3600);
+        setPresenceAgent(false);
+    }
+    
+    public void initialize(URI uri, Map<String, Object> parameters,
+            SipComponent component) {
+        this.setParameters(parameters);
+        this.setComponent(component);
+        this.setUri(uri);
+    }
+
+    public void parseURI() throws Exception {
+        protocol = uri.getScheme();
+        
+        if ((!protocol.equalsIgnoreCase("sip")) && (!protocol.equalsIgnoreCase("sips"))) {
+            throw new IllegalArgumentException("Unrecognized SIP protocol: " + protocol + " for uri: " + uri);
+        }
+
+        Map<String, Object> settings = URISupport.parseParameters(uri);        
+
+        if (settings.containsKey("stackName")) {
+            setStackName((String) settings.get("stackName"));
+        }
+        if (settings.containsKey("transport")) {
+            setTransport((String) settings.get("transport"));
+        } 
+        if (settings.containsKey("maxMessageSize")) {
+            setMaxMessageSize((String) settings.get("maxMessageSize"));
+        } 
+        if (settings.containsKey("cacheConnections")) {
+            setCacheConnections((String) settings.get("cacheConnections"));
+        }
+        if (settings.containsKey("contentType")) {
+            setContentType((String) settings.get("contentType"));
+        }
+        if (settings.containsKey("contentSubType")) {
+            setContentSubType((String) settings.get("contentSubType"));
+        }
+        if (settings.containsKey("maxForwards")) {
+            setMaxForwards(Integer.valueOf((String) settings.get("maxForwards")));
+        }
+        if (settings.containsKey("receiveTimeoutMillis")) {
+            setReceiveTimeoutMillis(Long.valueOf((String) settings.get("receiveTimeoutMillis")));
+        }
+        if (settings.containsKey("eventHeaderName")) {
+            setEventHeaderName((String) settings.get("eventHeaderName"));
+        } 
+        if (settings.containsKey("eventId")) {
+            setEventId((String) settings.get("eventId"));
+        }
+        if (settings.containsKey("useRouterForAllUris")) {
+            setUseRouterForAllUris((String) settings.get("useRouterForAllUris"));
+        }
+        if (settings.containsKey("msgExpiration")) {
+            setMsgExpiration(Integer.valueOf((String) settings.get("msgExpiration")));
+        }
+        if (settings.containsKey("presenceAgent")) {
+            setPresenceAgent(Boolean.valueOf((String) settings.get("presenceAgent")));
+        }
+
+        if (!consumer) {
+            if (settings.containsKey("fromUser")) {
+                setFromUser((String) settings.get("fromUser"));
+            }
+            if (settings.containsKey("fromHost")) {
+                setFromHost((String) settings.get("fromHost"));
+            } 
+            if (settings.containsKey("fromPort")) {
+                setFromPort(Integer.valueOf((String) settings.get("fromPort")));
+            } 
+            setToUser(uri.getUserInfo());
+            setToHost(uri.getHost());
+            setToPort(uri.getPort());
+        } else {
+            setFromUser(uri.getUserInfo());
+            setFromHost(uri.getHost());
+            setFromPort(uri.getPort());
+            if (!presenceAgent) {
+                if (settings.containsKey("toUser")) {
+                    setToUser((String) settings.get("toUser"));
+                }
+                if (settings.containsKey("toHost")) {
+                    setToHost((String) settings.get("toHost"));
+                } 
+                if (settings.containsKey("toPort")) {
+                    setToPort(Integer.valueOf((String) settings.get("toPort")));
+                } 
+            }
+        }
+        nistDebugLog = component.getAndRemoveParameter(parameters, "implementationDebugLogFile", String.class, null);
+        nistServerLog = component.getAndRemoveParameter(parameters, "implementationServerLogFile", String.class, null);
+        nistTraceLevel = component.getAndRemoveParameter(parameters, "implementationTraceLevel", String.class, "0");
+        
+        LOG.trace("Consumer:" + consumer + " StackName:" + stackName);
+        LOG.trace("From User: " + getFromUser() + " From host: " + getFromHost() + " From Port: " + getFromPort());
+         
+        createFactoriesAndHeaders(parameters, component);
+        
+        sipUri = component.resolveAndRemoveReferenceParameter(parameters, "sipUri", SipURI.class, null);
+        if (sipUri == null) {
+            sipUri = addressFactory.createSipURI(getToUser(), getToHost() + ":" + getToPort());
+        }
+
+        ObjectHelper.notNull(fromUser, "From User");
+        ObjectHelper.notNull(fromHost, "From Host");
+        ObjectHelper.notNull(fromPort, "From Port");
+        ObjectHelper.notNull(eventHeader, "Event Header");
+        ObjectHelper.notNull(eventHeaderName, "Event Header Name");        
+        ObjectHelper.notNull(eventId, "Event Id");        
+    }    
+
+    private void createFactoriesAndHeaders(Map<String, Object> parameters, SipComponent component) throws Exception {
+        headerFactory = sipFactory.createHeaderFactory();
+        addressFactory = sipFactory.createAddressFactory();
+        setMessageFactory(sipFactory.createMessageFactory());
+        
+        fromHeader = component.resolveAndRemoveReferenceParameter(parameters, "fromHeader", FromHeader.class, null);
+        if (fromHeader == null) { 
+            createFromHeader();
+        }
+        if (!presenceAgent) {
+            toHeader = component.resolveAndRemoveReferenceParameter(parameters, "toHeader", ToHeader.class, null);
+            if (toHeader == null) {
+                createToHeader();
+            }
+        }
+        viaHeaders = component.resolveAndRemoveReferenceParameter(parameters, "viaHeaders", ArrayList.class, null);
+        if (viaHeaders == null) {        
+            createViaHeaders();
+        }
+        contentTypeHeader = component.resolveAndRemoveReferenceParameter(parameters, "contentTypeHeader", ContentTypeHeader.class, null);
+        if (contentTypeHeader == null) {
+            createContentTypeHeader();
+        }
+
+        callIdHeader = component.resolveAndRemoveReferenceParameter(parameters, "callIdHeader", CallIdHeader.class, null);
+        
+        maxForwardsHeader = component.resolveAndRemoveReferenceParameter(parameters, "maxForwardsHeader", MaxForwardsHeader.class, null);
+        if (maxForwardsHeader == null) {        
+            createMaxForwardsHeader();
+        }
+        
+        // Optional Headers
+        eventHeader = component.resolveAndRemoveReferenceParameter(parameters, "eventHeader", EventHeader.class, null);
+        if (eventHeader == null) {
+            createEventHeader();
+        }        
+        contactHeader = component.resolveAndRemoveReferenceParameter(parameters, "contactHeader", ContactHeader.class, null);
+        if (contactHeader == null) {
+            createContactHeader();
+        }
+        expiresHeader = component.resolveAndRemoveReferenceParameter(parameters, "expiresHeader", ExpiresHeader.class, null);
+        if (expiresHeader == null) {
+            createExpiresHeader();
+        }
+        extensionHeader = component.resolveAndRemoveReferenceParameter(parameters, "extensionHeader", ExtensionHeader.class, null);
+        
+    }
+
+    public Request createSipRequest(long sequenceNumber, String requestMethod, Object body) throws ParseException, InvalidArgumentException {
+        //SipConfiguration configuration = sipPublisher.getConfiguration();
+        CSeqHeader cSeqHeader = getHeaderFactory().createCSeqHeader(sequenceNumber, requestMethod);
+
+        // Create the request.
+        Request request = getMessageFactory().createRequest(
+            getSipUri(), 
+            requestMethod, 
+            getCallIdHeader(), 
+            cSeqHeader, 
+            getFromHeader(),
+            getToHeader(), 
+            getViaHeaders(), 
+            getMaxForwardsHeader());
+        
+        if (getEventHeader() != null) {
+            request.addHeader(getEventHeader());
+        }
+        if (getExpiresHeader() != null) {
+            request.addHeader(getExpiresHeader());
+        }
+        if (getContactHeader() != null) {
+            request.addHeader(getContactHeader());
+        }
+        if (getExtensionHeader() != null) {
+            request.addHeader(getExtensionHeader());
+        }
+        request.setContent(body, getContentTypeHeader());
+        
+        return request;       
+    }
+    
+    private void createFromHeader() throws ParseException {
+        SipURI fromAddress = getAddressFactory().createSipURI(getFromUser(), getFromHost());
+        fromAddress.setPort(Integer.valueOf(getFromPort()).intValue());
+        Address fromNameAddress = addressFactory.createAddress(fromAddress);
+        fromNameAddress.setDisplayName(getFromUser());
+        
+        setFromHeader(headerFactory.createFromHeader(fromNameAddress, getFromUser() + "_Header"));        
+    }
+    
+    private void createToHeader() throws ParseException {
+        SipURI toAddress = getAddressFactory().createSipURI(getToUser(), getToHost());
+        toAddress.setPort(getToPort());
+        Address toNameAddress = addressFactory.createAddress(toAddress);
+        toNameAddress.setDisplayName(getToUser());
+        
+        setToHeader(headerFactory.createToHeader(toNameAddress, getToUser() + "_Header"));
+    }
+
+    private void createViaHeaders() throws ParseException, InvalidArgumentException {
+        viaHeaders = new ArrayList();
+        ViaHeader viaHeader = headerFactory.createViaHeader(getFromHost(), getFromPort(),
+                getTransport(), null);
+
+        viaHeaders.add(viaHeader);       
+    }
+
+    private void createContentTypeHeader() throws ParseException {
+        setContentTypeHeader(headerFactory.createContentTypeHeader(getContentType(), getContentSubType()));   
+    }
+    
+    private void createMaxForwardsHeader() throws ParseException, InvalidArgumentException {
+        setMaxForwardsHeader(headerFactory.createMaxForwardsHeader(getMaxForwards()));   
+    }
+
+    private void createEventHeader() throws ParseException {
+        eventHeader = getHeaderFactory().createEventHeader(getEventHeaderName());
+        eventHeader.setEventId(getEventId());        
+    }
+    
+    private void createContactHeader() throws ParseException {
+        SipURI contactURI = addressFactory.createSipURI(getFromUser(), getFromHost());
+        contactURI.setTransportParam(getTransport());
+        contactURI.setPort(Integer.valueOf(getFromPort()).intValue());
+        Address contactAddress = addressFactory.createAddress(contactURI);
+
+        // Add the contact address.
+        contactAddress.setDisplayName(getFromUser());
+
+        contactHeader = headerFactory.createContactHeader(contactAddress);
+    }
+
+    private void createExpiresHeader() throws ParseException, InvalidArgumentException {
+        expiresHeader = getHeaderFactory().createExpiresHeader(getMsgExpiration());        
+    }
+    
+    Properties createInitialProperties() {
+        Properties properties = new Properties();
+        properties.setProperty("javax.sip.STACK_NAME", getStackName());
+        properties.setProperty("gov.nist.javax.sip.MAX_MESSAGE_SIZE", getMaxMessageSize());
+        properties.setProperty("gov.nist.javax.sip.CACHE_CLIENT_CONNECTIONS", getCacheConnections());
+        properties.setProperty("javax.sip.USE_ROUTER_FOR_ALL_URIS", getUseRouterForAllUris());
+        if ((nistDebugLog != null) && (nistServerLog != null)) {
+            properties.setProperty("gov.nist.javax.sip.DEBUG_LOG", nistDebugLog);
+            properties.setProperty("gov.nist.javax.sip.SERVER_LOG", nistServerLog);
+            properties.setProperty("gov.nist.javax.sip.TRACE_LEVEL", nistTraceLevel);
+        }
+        
+        return properties;
+    }
+
+    public AddressFactory getAddressFactory() {
+        return addressFactory;
+    }
+
+    public void setAddressFactory(AddressFactory addressFactory) {
+        this.addressFactory = addressFactory;
+    }
+
+    public MessageFactory getMessageFactory() {
+        return messageFactory;
+    }
+
+    public void setMessageFactory(MessageFactory messageFactory) {
+        this.messageFactory = messageFactory;
+    }
+
+    public HeaderFactory getHeaderFactory() {
+        return headerFactory;
+    }
+
+    public void setHeaderFactory(HeaderFactory headerFactory) {
+        this.headerFactory = headerFactory;
+    }
+
+    public SipStack getSipStack() {
+        return sipStack;
+    }
+
+    public void setSipStack(SipStack sipStack) {
+        this.sipStack = sipStack;
+    }
+
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public SipURI getSipUri() {
+        return sipUri;
+    }
+
+    public void setSipUri(SipURI sipUri) {
+        this.sipUri = sipUri;
+    }
+
+    public String getStackName() {
+        return stackName;
+    }
+
+    public void setStackName(String stackName) {
+        this.stackName = stackName;
+    }
+
+    public String getTransport() {
+        return transport;
+    }
+
+    public void setTransport(String transport) {
+        this.transport = transport;
+    }
+
+    public String getMaxMessageSize() {
+        return maxMessageSize;
+    }
+
+    public void setMaxMessageSize(String maxMessageSize) {
+        this.maxMessageSize = maxMessageSize;
+    }
+
+    public String getAutomaticDialogSupport() {
+        return automaticDialogSupport;
+    }
+
+    public void setAutomaticDialogSupport(String automaticDialogSupport) {
+        this.automaticDialogSupport = automaticDialogSupport;
+    }
+
+    public String getCacheConnections() {
+        return cacheConnections;
+    }
+
+    public void setCacheConnections(String cacheConnections) {
+        this.cacheConnections = cacheConnections;
+    }
+
+    public ListeningPoint getListeningPoint() {
+        return listeningPoint;
+    }
+
+    public void setListeningPoint(ListeningPoint listeningPoint) {
+        this.listeningPoint = listeningPoint;
+    }
+
+    public void setContentType(String contentType) {
+        this.contentType = contentType;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    public void setContentSubType(String contentSubType) {
+        this.contentSubType = contentSubType;
+    }
+
+    public String getContentSubType() {
+        return contentSubType;
+    }
+
+    public void setMaxForwards(int maxForwards) {
+        this.maxForwards = maxForwards;
+    }
+
+    public int getMaxForwards() {
+        return maxForwards;
+    }
+
+    public void setReceiveTimeoutMillis(long receiveTimeoutMillis) {
+        this.receiveTimeoutMillis = receiveTimeoutMillis;
+    }
+
+    public long getReceiveTimeoutMillis() {
+        return receiveTimeoutMillis;
+    }
+
+    public void setParameters(Map<String, Object> parameters) {
+        this.parameters = parameters;
+    }
+
+    public Map<String, Object> getParameters() {
+        return parameters;
+    }
+
+    public void setComponent(SipComponent component) {
+        this.component = component;
+    }
+
+    public SipComponent getComponent() {
+        return component;
+    }
+
+    public String getNistServerLog() {
+        return nistServerLog;
+    }
+
+    public void setNistServerLog(String nistServerLog) {
+        this.nistServerLog = nistServerLog;
+    }
+
+    public String getNistDebugLog() {
+        return nistDebugLog;
+    }
+
+    public void setNistDebugLog(String nistDebugLog) {
+        this.nistDebugLog = nistDebugLog;
+    }
+
+    public String getNistTraceLevel() {
+        return nistTraceLevel;
+    }
+
+    public void setNistTraceLevel(String nistTraceLevel) {
+        this.nistTraceLevel = nistTraceLevel;
+    }
+
+    public SipFactory getSipFactory() {
+        return sipFactory;
+    }
+
+    public void setSipFactory(SipFactory sipFactory) {
+        this.sipFactory = sipFactory;
+    }
+
+    public String getFromUser() {
+        return fromUser;
+    }
+
+    public void setFromUser(String fromUser) {
+        this.fromUser = fromUser;
+    }
+
+    public String getFromHost() {
+        return fromHost;
+    }
+
+    public void setFromHost(String fromHost) {
+        this.fromHost = fromHost;
+    }
+
+    public int getFromPort() {
+        return fromPort;
+    }
+
+    public void setFromPort(int fromPort) {
+        this.fromPort = fromPort;
+    }
+
+    public String getToUser() {
+        return toUser;
+    }
+
+    public void setToUser(String toUser) {
+        this.toUser = toUser;
+    }
+
+    public String getToHost() {
+        return toHost;
+    }
+
+    public void setToHost(String toHost) {
+        this.toHost = toHost;
+    }
+
+    public int getToPort() {
+        return toPort;
+    }
+
+    public void setToPort(int toPort) {
+        this.toPort = toPort;
+    }
+
+    public FromHeader getFromHeader() {
+        return fromHeader;
+    }
+
+    public void setFromHeader(FromHeader fromHeader) {
+        this.fromHeader = fromHeader;
+    }
+
+    public ToHeader getToHeader() {
+        return toHeader;
+    }
+
+    public void setToHeader(ToHeader toHeader) {
+        this.toHeader = toHeader;
+    }
+
+    public ArrayList<ViaHeader> getViaHeaders() {
+        return viaHeaders;
+    }
+
+    public void setViaHeaders(ArrayList<ViaHeader> viaHeaders) {
+        this.viaHeaders = viaHeaders;
+    }
+
+    public ContentTypeHeader getContentTypeHeader() {
+        return contentTypeHeader;
+    }
+
+    public void setContentTypeHeader(ContentTypeHeader contentTypeHeader) {
+        this.contentTypeHeader = contentTypeHeader;
+    }
+
+    public CallIdHeader getCallIdHeader() {
+        return callIdHeader;
+    }
+
+    public void setCallIdHeader(CallIdHeader callIdHeader) {
+        this.callIdHeader = callIdHeader;
+    }
+
+    public MaxForwardsHeader getMaxForwardsHeader() {
+        return maxForwardsHeader;
+    }
+
+    public void setMaxForwardsHeader(MaxForwardsHeader maxForwardsHeader) {
+        this.maxForwardsHeader = maxForwardsHeader;
+    }
+
+    public ContactHeader getContactHeader() {
+        return contactHeader;
+    }
+
+    public void setContactHeader(ContactHeader contactHeader) {
+        this.contactHeader = contactHeader;
+    }
+
+    public ExtensionHeader getExtensionHeader() {
+        return extensionHeader;
+    }
+
+    public void setExtensionHeader(ExtensionHeader extensionHeader) {
+        this.extensionHeader = extensionHeader;
+    }
+
+    public void setUri(URI uri) {
+        this.uri = uri;
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public void setConsumer(boolean consumer) {
+        this.consumer = consumer;
+    }
+
+    public boolean isConsumer() {
+        return consumer;
+    }
+
+    public void setClientTransactionId(ClientTransaction clientTransactionId) {
+        this.clientTransactionId = clientTransactionId;
+    }
+
+    public ClientTransaction getClientTransactionId() {
+        return clientTransactionId;
+    }
+
+    public void setDialog(Dialog dialog) {
+        this.dialog = dialog;
+    }
+
+    public Dialog getDialog() {
+        return dialog;
+    }
+
+    public void setEventHeader(EventHeader eventHeader) {
+        this.eventHeader = eventHeader;
+    }
+
+    public EventHeader getEventHeader() {
+        return eventHeader;
+    }
+
+    public void setEventHeaderName(String eventHeaderName) {
+        this.eventHeaderName = eventHeaderName;
+    }
+
+    public String getEventHeaderName() {
+        return eventHeaderName;
+    }
+
+    public void setEventId(String eventId) {
+        this.eventId = eventId;
+    }
+
+    public String getEventId() {
+        return eventId;
+    }
+
+    public void setUseRouterForAllUris(String useRouterForAllUris) {
+        this.useRouterForAllUris = useRouterForAllUris;
+    }
+
+    public String getUseRouterForAllUris() {
+        return useRouterForAllUris;
+    }
+
+    public int getMsgExpiration() {
+        return msgExpiration;
+    }
+
+    public void setMsgExpiration(int msgExpiration) {
+        this.msgExpiration = msgExpiration;
+    }
+
+    public ExpiresHeader getExpiresHeader() {
+        return expiresHeader;
+    }
+
+    public void setExpiresHeader(ExpiresHeader expiresHeader) {
+        this.expiresHeader = expiresHeader;
+    }
+
+    public boolean isPresenceAgent() {
+        return presenceAgent;
+    }
+
+    public void setPresenceAgent(boolean presenceAgent) {
+        this.presenceAgent = presenceAgent;
+    }
+    
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,58 @@
+/**
+ * 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.sip;
+
+import org.apache.camel.Component;
+import org.apache.camel.Consumer;
+import org.apache.camel.Processor;
+import org.apache.camel.Producer;
+import org.apache.camel.impl.DefaultEndpoint;
+
+public class SipEndpoint extends DefaultEndpoint {
+    private SipConfiguration configuration;
+
+    public SipEndpoint(String endpointUri, Component component, SipConfiguration configuration) {
+        super(endpointUri, component);
+        this.configuration = configuration;
+    }
+
+    public Consumer createConsumer(Processor processor) throws Exception {
+        if (configuration.isPresenceAgent()) {
+            return new SipPresenceAgent(this, processor, configuration);
+        } else {
+            return new SipSubscriber(this, processor, configuration);
+        }
+    }
+
+    public Producer createProducer() throws Exception {
+        return new SipPublisher(this, configuration);
+    }
+    
+    public boolean isSingleton() {
+        return false;
+    }
+
+    public SipConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(SipConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    
+}
\ No newline at end of file

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,90 @@
+/**
+ * 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.sip;
+
+import java.util.Properties;
+
+import javax.sip.SipProvider;
+import javax.sip.SipStack;
+
+import org.apache.camel.Processor;
+import org.apache.camel.component.sip.listener.SipPresenceAgentListener;
+import org.apache.camel.impl.DefaultConsumer;
+
+public class SipPresenceAgent extends DefaultConsumer {
+    private SipConfiguration configuration;
+    private SipPresenceAgentListener sipPresenceAgentListener;
+    private SipProvider provider; 
+    private SipStack sipStack;
+    
+    public SipPresenceAgent(SipEndpoint sipEndpoint, Processor processor,
+        SipConfiguration configuration) {
+        super(sipEndpoint, processor);
+        this.configuration = sipEndpoint.getConfiguration();
+        this.configuration.setConsumer(true);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        Properties properties = configuration.createInitialProperties();
+        setSipStack(configuration.getSipFactory().createSipStack(properties));
+        
+        configuration.parseURI();
+        sipPresenceAgentListener = new SipPresenceAgentListener(this);
+        configuration.setListeningPoint(
+                sipStack.createListeningPoint(configuration.getFromHost(), 
+                    Integer.valueOf(configuration.getFromPort()).intValue(), 
+                    configuration.getTransport()));
+        provider = getSipStack().createSipProvider(configuration.getListeningPoint());
+        provider.addSipListener(sipPresenceAgentListener);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop(); 
+        getSipStack().deleteListeningPoint(configuration.getListeningPoint());
+        provider.removeSipListener(sipPresenceAgentListener);
+        getSipStack().deleteSipProvider(provider);
+        getSipStack().stop();
+    }
+
+    public SipConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(SipConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public SipProvider getProvider() {
+        return provider;
+    }
+
+    public void setProvider(SipProvider provider) {
+        this.provider = provider;
+    }
+
+    public void setSipStack(SipStack sipStack) {
+        this.sipStack = sipStack;
+    }
+
+    public SipStack getSipStack() {
+        return sipStack;
+    }
+    
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPresenceAgent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,110 @@
+/**
+ * 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.sip;
+
+import java.util.Properties;
+
+import javax.sip.ListeningPoint;
+import javax.sip.SipProvider;
+import javax.sip.SipStack;
+import javax.sip.message.Request;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.ServicePoolAware;
+import org.apache.camel.component.sip.listener.SipPublishListener;
+import org.apache.camel.impl.DefaultProducer;
+
+public class SipPublisher extends DefaultProducer implements ServicePoolAware {
+    private SipConfiguration configuration;
+    private long sequenceNumber = 1;
+    private SipPublishListener sipPublishListener;
+    private SipProvider provider; 
+    private SipStack sipStack;
+
+    public SipPublisher(SipEndpoint sipEndpoint, SipConfiguration configuration) {
+        super(sipEndpoint);
+        this.setConfiguration(configuration);
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        Properties properties = configuration.createInitialProperties();
+        setSipStack(configuration.getSipFactory().createSipStack(properties));
+        
+        configuration.parseURI();
+        if (sipPublishListener == null) {
+            sipPublishListener = new SipPublishListener(this);
+        }
+        
+        configuration.setListeningPoint(
+                sipStack.createListeningPoint(configuration.getFromHost(), Integer.valueOf(configuration.getFromPort()).intValue(), configuration.getTransport()));
+        
+        boolean found = false;
+        if (provider != null) {
+            for (ListeningPoint listeningPoint : provider.getListeningPoints()) {
+                if (listeningPoint.getIPAddress().equalsIgnoreCase(configuration.getListeningPoint().getIPAddress()) 
+                    && (listeningPoint.getPort() == configuration.getListeningPoint().getPort())) {
+                    found = true;
+                }
+            }
+        }
+        if (!found) {
+            provider = getSipStack().createSipProvider(configuration.getListeningPoint());
+            provider.addSipListener(sipPublishListener);
+            configuration.setCallIdHeader(provider.getNewCallId());
+        }
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop();
+        getSipStack().deleteListeningPoint(configuration.getListeningPoint());
+        provider.removeSipListener(sipPublishListener);
+        getSipStack().deleteSipProvider(provider);
+        getSipStack().stop();
+    }
+    
+    public void process(Exchange exchange) throws Exception {
+        String requestMethod = exchange.getIn().getHeader("REQUEST_METHOD", String.class);
+        if (requestMethod == null) {
+            throw new CamelException("Missing mandatory Header in REQUEST_HEADER in exchange");
+        }
+        Object body = exchange.getIn().getBody();
+        
+        Request request = configuration.createSipRequest(sequenceNumber, requestMethod, body);
+        provider.sendRequest(request);
+        
+    }
+
+    public void setConfiguration(SipConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public SipConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setSipStack(SipStack sipStack) {
+        this.sipStack = sipStack;
+    }
+
+    public SipStack getSipStack() {
+        return sipStack;
+    }
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipPublisher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,116 @@
+/**
+ * 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.sip;
+
+import java.util.Properties;
+
+import javax.sip.ClientTransaction;
+import javax.sip.Dialog;
+import javax.sip.ListeningPoint;
+import javax.sip.SipProvider;
+import javax.sip.SipStack;
+import javax.sip.message.Request;
+
+import org.apache.camel.Processor;
+import org.apache.camel.component.sip.listener.SipSubscriptionListener;
+import org.apache.camel.impl.DefaultConsumer;
+
+public class SipSubscriber extends DefaultConsumer {
+    private SipConfiguration configuration;
+    private SipSubscriptionListener sipSubscriptionListener;
+    private SipProvider provider;
+    private Dialog subscriberDialog;
+    private SipStack sipStack;
+
+    public SipSubscriber(SipEndpoint sipEndpoint, Processor processor, SipConfiguration configuration) {
+        super(sipEndpoint, processor);
+        this.configuration = sipEndpoint.getConfiguration();
+        this.configuration.setConsumer(true);
+
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+        Properties properties = configuration.createInitialProperties();
+        sipStack = configuration.getSipFactory().createSipStack(properties);
+        
+        configuration.parseURI();
+        sipSubscriptionListener = new SipSubscriptionListener(this);
+        ListeningPoint listeningPoint = 
+            sipStack.createListeningPoint(configuration.getFromHost(), Integer.valueOf(configuration.getFromPort()).intValue(), configuration.getTransport());
+        configuration.setListeningPoint(listeningPoint);
+        provider = sipStack.createSipProvider(configuration.getListeningPoint());
+        provider.addSipListener(sipSubscriptionListener);
+        
+        if (configuration.getCallIdHeader() == null) {
+            configuration.setCallIdHeader(provider.getNewCallId());
+        }
+        
+        // Create the Subscription request to register with the presence agent and receive notifications.
+        configuration.setCallIdHeader(provider.getNewCallId());
+        Request request = configuration.createSipRequest(1, Request.SUBSCRIBE, configuration.getEventHeaderName());
+            
+        // Create the subscriber transaction from request.
+        ClientTransaction subscriberTransactionId = provider.getNewClientTransaction(request);
+            
+        // Add an Event header for the subscription.
+        request.addHeader(configuration.getEventHeader());
+        subscriberDialog = subscriberTransactionId.getDialog();
+
+        // Send the outgoing subscription request.
+        subscriberTransactionId.sendRequest();
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        super.doStop(); 
+    }
+
+    public SipConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(SipConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public void setSipSubscriptionListener(SipSubscriptionListener sipSubscriptionListener) {
+        this.sipSubscriptionListener = sipSubscriptionListener;
+    }
+
+    public SipSubscriptionListener getSipSubscriptionListener() {
+        return sipSubscriptionListener;
+    }
+
+    public void setSipStack(SipStack sipStack) {
+        this.sipStack = sipStack;
+    }
+
+    public SipStack getSipStack() {
+        return sipStack;
+    }
+
+    public SipProvider getProvider() {
+        return provider;
+    }
+
+    public void setProvider(SipProvider provider) {
+        this.provider = provider;
+    }
+
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/SipSubscriber.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,82 @@
+/**
+ * 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.sip.listener;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public interface SipMessageCodes {
+    Map<Integer, String> SIP_MESSAGE_CODES = 
+        new HashMap<Integer, String>() 
+        {
+            {
+                put(new Integer(100), "Trying");
+                put(new Integer(180), "Ringing");
+                put(new Integer(181), "Call Being Forwarded");
+                put(new Integer(182), "Call Queued");
+                put(new Integer(183), "Session Progress");
+                put(new Integer(200), "OK");
+                put(new Integer(202), "Accepted");
+                put(new Integer(300), "Multiple Choices");
+                put(new Integer(301), "Moved Permanently");
+                put(new Integer(302), "Moved Temporarily");
+                put(new Integer(305), "Use Proxy");
+                put(new Integer(380), "Alternative Service");
+                put(new Integer(400), "Bad Request");
+                put(new Integer(401), "Unauthorized");
+                put(new Integer(402), "Payment Required");
+                put(new Integer(403), "Forbidden");
+                put(new Integer(404), "Not Found");
+                put(new Integer(405), "Method Not Allowed");
+                put(new Integer(406), "Not Acceptable");
+                put(new Integer(407), "Proxy Authentication Required");
+                put(new Integer(408), "Request Timeout");
+                put(new Integer(409), "Conflict");
+                put(new Integer(410), "Gone");
+                put(new Integer(411), "Length Required");
+                put(new Integer(413), "Request Entity Too Large");
+                put(new Integer(414), "Request URI Too Long");
+                put(new Integer(415), "Unsupported Media Type");
+                put(new Integer(416), "Unsupported URI Scheme");
+                put(new Integer(420), "Bad Extension");
+                put(new Integer(421), "Extension Required");
+                put(new Integer(423), "Interval Too Brief");
+                put(new Integer(480), "Temporarily Unavailable");
+                put(new Integer(481), "Call/Transaction Does Not Exist");
+                put(new Integer(482), "Loop Detected");
+                put(new Integer(483), "Too Many Hops");
+                put(new Integer(484), "Address Incomplete");
+                put(new Integer(485), "Ambiguous");
+                put(new Integer(486), "Busy Here");
+                put(new Integer(487), "Request Terminated");
+                put(new Integer(488), "Not Acceptable Here");
+                put(new Integer(491), "Request Pending");
+                put(new Integer(493), "Undecipherable");
+                put(new Integer(500), "Server Internal Error");
+                put(new Integer(501), "Not Implemented");
+                put(new Integer(502), "Bad Gateway");
+                put(new Integer(503), "Service Unavailable");
+                put(new Integer(504), "Server Time-Out");
+                put(new Integer(505), "Version Not Supported");
+                put(new Integer(513), "Message Too Large");
+                put(new Integer(600), "Busy Everywhere");
+                put(new Integer(603), "Declined");
+                put(new Integer(604), "Does Not Exist Anywhere");
+                put(new Integer(605), "Not Acceptable");
+            }
+        };
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipMessageCodes.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,231 @@
+/**
+ * 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.sip.listener;
+
+import java.text.ParseException;
+import java.util.UUID;
+
+import javax.sip.ClientTransaction;
+import javax.sip.Dialog;
+import javax.sip.DialogTerminatedEvent;
+import javax.sip.IOExceptionEvent;
+import javax.sip.RequestEvent;
+import javax.sip.ResponseEvent;
+import javax.sip.ServerTransaction;
+import javax.sip.SipException;
+import javax.sip.SipListener;
+import javax.sip.SipProvider;
+import javax.sip.TransactionTerminatedEvent;
+import javax.sip.address.SipURI;
+import javax.sip.header.EventHeader;
+import javax.sip.header.SubscriptionStateHeader;
+import javax.sip.header.ToHeader;
+import javax.sip.message.Request;
+import javax.sip.message.Response;
+
+import org.apache.camel.component.sip.SipPresenceAgent;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class SipPresenceAgentListener implements SipListener, SipMessageCodes {
+    private static final transient Log LOG = LogFactory.getLog(SipPresenceAgentListener.class);
+    protected Dialog dialog;
+    protected int notifyCount;
+    private SipPresenceAgent sipPresenceAgent;
+
+
+    public SipPresenceAgentListener(SipPresenceAgent sipPresenceAgent) {
+        this.sipPresenceAgent = sipPresenceAgent;
+    }
+
+    public void processRequest(RequestEvent requestEvent) {
+        Request request = requestEvent.getRequest();
+        ServerTransaction serverTransactionId = requestEvent.getServerTransaction();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Request: " + request.getMethod()); 
+            LOG.debug("Server Transaction Id:" + serverTransactionId);
+        }
+
+        if (request.getMethod().equals(Request.SUBSCRIBE)) {
+            processSubscribe(requestEvent, serverTransactionId);
+        } else if (request.getMethod().equals(Request.PUBLISH)) {
+            processPublish(requestEvent, serverTransactionId);
+        } else {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Received expected request with method: " + request.getMethod() + ". No further processing done");
+            }
+        }
+    }
+    
+    private void sendNotification(EventHeader eventHeader, boolean isInitial, Object body) throws SipException, ParseException {
+        /*
+         * NOTIFY requests MUST contain a "Subscription-State" header with a
+         * value of "active", "pending", or "terminated". The "active" value
+         * indicates that the subscription has been accepted and has been
+         * authorized (in most cases; see section 5.2.). The "pending" value
+         * indicates that the subscription has been received, but that
+         * policy information is insufficient to accept or deny the
+         * subscription at this time. The "terminated" value indicates that
+         * the subscription is not active.
+         */
+        
+        Request notifyRequest = dialog.createRequest("NOTIFY");
+
+        // Mark the contact header, to check that the remote contact is updated
+        ((SipURI)sipPresenceAgent.getConfiguration().getContactHeader().getAddress().getURI()).setParameter(
+                sipPresenceAgent.getConfiguration().getFromUser(), sipPresenceAgent.getConfiguration().getFromHost());
+
+        SubscriptionStateHeader sstate;
+        if (isInitial) {
+            // Initial state is pending, second time we assume terminated (Expires==0)
+            sstate = 
+                sipPresenceAgent.getConfiguration().getHeaderFactory().createSubscriptionStateHeader(isInitial ? SubscriptionStateHeader.PENDING : SubscriptionStateHeader.TERMINATED);
+    
+            // Need a reason for terminated
+            if (sstate.getState().equalsIgnoreCase("terminated")) {
+                sstate.setReasonCode("deactivated");
+            }
+        } else {
+            sstate = sipPresenceAgent.getConfiguration().getHeaderFactory().createSubscriptionStateHeader(SubscriptionStateHeader.ACTIVE);
+        }
+
+        notifyRequest.addHeader(sstate);
+        notifyRequest.setHeader(eventHeader);
+        notifyRequest.setHeader(sipPresenceAgent.getConfiguration().getContactHeader());
+        notifyRequest.setContent(body, sipPresenceAgent.getConfiguration().getContentTypeHeader());
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Sending the following NOTIFY request to Subscriber: " + notifyRequest);
+        }
+        
+        ClientTransaction clientTransactionId = sipPresenceAgent.getProvider().getNewClientTransaction(notifyRequest);
+
+        dialog.sendRequest(clientTransactionId);
+    }
+    
+    private void processPublish(RequestEvent requestEvent,
+            ServerTransaction serverTransactionId) {
+        try {
+            Request request = requestEvent.getRequest();
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("SipPresenceAgentListener: Received a Publish request, sending OK");
+                LOG.debug("SipPresenceAgentListener request: " + request);
+            }
+            EventHeader eventHeader = (EventHeader) requestEvent.getRequest().getHeader(EventHeader.NAME);
+            Response response = sipPresenceAgent.getConfiguration().getMessageFactory().createResponse(202, request);
+            sipPresenceAgent.getProvider().sendResponse(response);
+
+            // Send notification to subscriber
+            sendNotification(eventHeader, false, request.getContent());
+                     
+        } catch (Exception e) {
+            LOG.error("Exception thrown during publish/notify processing in the Sip Presence Agent Listener", e);
+        }
+    }
+
+    public void processSubscribe(RequestEvent requestEvent,
+            ServerTransaction serverTransaction) {
+        SipProvider sipProvider = (SipProvider) requestEvent.getSource();
+        Request request = requestEvent.getRequest();
+        try {
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("SipPresenceAgentListener: Received a Subscribe request, sending OK");
+                LOG.debug("SipPresenceAgentListener request: " + request);
+            }
+            EventHeader eventHeader = (EventHeader) request.getHeader(EventHeader.NAME);
+            if (eventHeader == null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("Cannot find event header.... dropping request.");
+                }
+                return;
+            }
+
+            // Always create a ServerTransaction, best as early as possible in the code
+            Response response = null;
+            ServerTransaction st = requestEvent.getServerTransaction();
+            if (st == null) {
+                st = sipProvider.getNewServerTransaction(request);
+            }
+
+            // Check if it is an initial SUBSCRIBE or a refresh / unsubscribe
+            boolean isInitial = requestEvent.getDialog() == null;
+            if (isInitial) {
+                String toTag = UUID.randomUUID().toString();
+                response = sipPresenceAgent.getConfiguration().getMessageFactory().createResponse(202, request);
+                ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME);
+                toHeader.setTag(toTag); // Application is supposed to set.
+
+                this.dialog = st.getDialog();
+                // subscribe dialogs do not terminate on bye.
+                this.dialog.terminateOnBye(false);
+            } else {
+                response = sipPresenceAgent.getConfiguration().getMessageFactory().createResponse(200, request);
+            }
+
+            // Both 2xx response to SUBSCRIBE and NOTIFY need a Contact
+            response.addHeader(sipPresenceAgent.getConfiguration().getContactHeader());
+
+            // Expires header is mandatory in 2xx responses to SUBSCRIBE
+            response.addHeader(sipPresenceAgent.getConfiguration().getExpiresHeader());
+            st.sendResponse(response);
+            
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("SipPresenceAgentListener: Sent OK Message");
+                LOG.debug("SipPresenceAgentListener response: " + response);
+            }
+            sendNotification(eventHeader, isInitial, request.getContent());
+
+        } catch (Throwable e) {
+            LOG.error("Exception thrown during Notify processing in the SipPresenceAgentListener.", e);
+        }
+    }
+
+    public synchronized void processResponse(ResponseEvent responseReceivedEvent) {
+        Response response = (Response) responseReceivedEvent.getResponse();
+        Integer statusCode = response.getStatusCode();
+        if (SIP_MESSAGE_CODES.containsKey(statusCode)) {
+            LOG.debug(SIP_MESSAGE_CODES.get(statusCode) + " received from Subscriber");
+        }
+    }
+
+    public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("TimeoutEvent received at Sip Subscription Listener");
+        }
+    }
+
+    public void processIOException(IOExceptionEvent exceptionEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("IOExceptionEvent received at SipPresenceAgentListener");
+        }
+    }
+
+    public void processTransactionTerminated(
+            TransactionTerminatedEvent transactionTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("TransactionTerminatedEvent received at SipPresenceAgentListener");
+        }
+    }
+
+    public void processDialogTerminated(
+            DialogTerminatedEvent dialogTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("DialogTerminatedEvent received at SipPresenceAgentListener");
+        }
+    }
+
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPresenceAgentListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,80 @@
+/**
+ * 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.sip.listener;
+
+import javax.sip.DialogTerminatedEvent;
+import javax.sip.IOExceptionEvent;
+import javax.sip.RequestEvent;
+import javax.sip.ResponseEvent;
+import javax.sip.SipListener;
+import javax.sip.TransactionTerminatedEvent;
+
+import org.apache.camel.component.sip.SipPublisher;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class SipPublishListener implements SipListener {
+    private static final transient Log LOG = LogFactory.getLog(SipPublishListener.class);
+    private SipPublisher sipPublisher;
+
+    public SipPublishListener(SipPublisher sipPublisher) {
+        this.setSipPublisher(sipPublisher);
+    }
+
+    public void processRequest(RequestEvent requestEvent) {
+        // The SipPublishListener associated with the SipPublisher
+        // may not accept incoming requests 
+    }
+
+    public void processResponse(ResponseEvent responseReceivedEvent) {  
+        // The SipPublishListener sends InOnly requests to the Presence Agent
+        // and only receives ACKs from the Presence Agent to satisfy the 
+        // Sip handshakeand. Hence any responses are not further processed.
+    }
+    
+    public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("processTimeout received at Sip Publish Listener");
+        }
+    }
+
+    public void processDialogTerminated(DialogTerminatedEvent dialogTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("processDialogTerminated received at Sip Publish Listener");
+        }
+    }
+
+    public void processIOException(IOExceptionEvent ioExceptionEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("IOExceptionEvent received at Sip Publish Listener");
+        }       
+    }
+
+    public void processTransactionTerminated(TransactionTerminatedEvent transactionTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("processTransactionTerminated received at Sip Publish Listener");
+        }
+    }
+
+    public void setSipPublisher(SipPublisher sipPublisher) {
+        this.sipPublisher = sipPublisher;
+    }
+
+    public SipPublisher getSipPublisher() {
+        return sipPublisher;
+    }
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipPublishListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java (added)
+++ camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,178 @@
+/**
+ * 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.sip.listener;
+
+import javax.sip.ClientTransaction;
+import javax.sip.Dialog;
+import javax.sip.DialogTerminatedEvent;
+import javax.sip.IOExceptionEvent;
+import javax.sip.RequestEvent;
+import javax.sip.ResponseEvent;
+import javax.sip.ServerTransaction;
+import javax.sip.SipListener;
+import javax.sip.SipProvider;
+import javax.sip.Transaction;
+import javax.sip.TransactionTerminatedEvent;
+import javax.sip.header.SubscriptionStateHeader;
+import javax.sip.header.ViaHeader;
+import javax.sip.message.Request;
+import javax.sip.message.Response;
+
+import org.apache.camel.CamelException;
+import org.apache.camel.Exchange;
+import org.apache.camel.ExchangePattern;
+import org.apache.camel.component.sip.SipSubscriber;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+public class SipSubscriptionListener implements SipListener {
+    private static final transient Log LOG = LogFactory.getLog(SipSubscriptionListener.class);
+    private SipSubscriber sipSubscriber;
+    private Dialog subscriberDialog;
+    private Dialog forkedDialog;
+    private ClientTransaction subscriberTransactionId;
+
+    public SipSubscriptionListener(SipSubscriber sipSubscriber) {
+        this.setSipSubscriber(sipSubscriber);
+    }
+
+    private void dispatchExchange(Object response) throws CamelException {
+        Exchange exchange;
+        
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Consumer Dispatching the received notification along the route");
+        }
+        exchange = sipSubscriber.getEndpoint().createExchange(ExchangePattern.InOnly);
+        exchange.getIn().setBody(response);
+        try {
+            sipSubscriber.getProcessor().process(exchange);
+        } catch (Exception e) {
+            throw new CamelException("Error in consumer while dispatching exchange", e);
+        }
+    }
+    
+    public void processRequest(RequestEvent requestReceivedEvent) {
+        Request request = requestReceivedEvent.getRequest();
+        ServerTransaction serverTransactionId = requestReceivedEvent
+                .getServerTransaction();
+        String viaBranch = ((ViaHeader)(request.getHeaders(ViaHeader.NAME).next())).getParameter("branch");
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Request: " + request.getMethod()); 
+            LOG.debug("Server Transaction Id:" + serverTransactionId);
+            LOG.debug("Received From Branch:" + viaBranch);
+        }
+
+        if (request.getMethod().equals(Request.NOTIFY)) {
+            processNotify(requestReceivedEvent, serverTransactionId);
+        } 
+
+    }
+
+    public synchronized void processNotify(RequestEvent requestEvent,
+            ServerTransaction serverTransactionId) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Notification received at Subscriber");
+        }
+        SipProvider provider = (SipProvider) requestEvent.getSource();
+        Request notify = requestEvent.getRequest();
+        try {
+            if (serverTransactionId == null) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.info("ServerTransaction is null. Creating new Server transaction");
+                }
+                serverTransactionId = provider.getNewServerTransaction(notify);
+            }
+            Dialog dialog = serverTransactionId.getDialog();
+
+            if (dialog != subscriberDialog) {
+                forkedDialog = dialog;
+            }
+            //Dispatch the response along the route
+            dispatchExchange(notify.getContent());
+            
+            // Send back an success response
+            Response response = sipSubscriber.getConfiguration().getMessageFactory().createResponse(200, notify);            
+            response.addHeader(sipSubscriber.getConfiguration().getContactHeader());
+            serverTransactionId.sendResponse(response);
+
+            SubscriptionStateHeader subscriptionState = (SubscriptionStateHeader) notify
+                    .getHeader(SubscriptionStateHeader.NAME);
+
+            // Subscription is terminated?
+            if (subscriptionState.getState().equalsIgnoreCase(SubscriptionStateHeader.TERMINATED)) {
+                if (LOG.isDebugEnabled()) {
+                    LOG.info("Subscription state is terminated. Deleting the current dialog");
+                }
+                dialog.delete();
+            }
+        } catch (Exception e) {
+            LOG.error("Exception thrown during Notify processing in the SipSubscriptionListener.", e);
+        }
+    }
+    
+    public void processResponse(ResponseEvent responseReceivedEvent) {
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Response received at Subscriber");
+        }
+        Response response = (Response) responseReceivedEvent.getResponse();
+        Transaction clientTransactionId = responseReceivedEvent.getClientTransaction();
+
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Response received with client transaction id " + clientTransactionId + ":" + response.getStatusCode());
+        }
+        if (clientTransactionId == null) {
+            if (LOG.isWarnEnabled()) {
+                LOG.warn("Stray response -- dropping ");
+            }
+            return;
+        }
+    }
+
+    public void processIOException(IOExceptionEvent exceptionEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("IOExceptionEvent received at Sip Subscription Listener");
+        }
+    }
+
+    public void processTransactionTerminated(
+            TransactionTerminatedEvent transactionTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("TransactionTerminatedEvent received at Sip Subscription Listener");
+        }
+    }
+
+    public void processDialogTerminated(
+            DialogTerminatedEvent dialogTerminatedEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("DialogTerminatedEvent received at Sip Subscription Listener");
+        }
+    }
+
+    public void processTimeout(javax.sip.TimeoutEvent timeoutEvent) {
+        if (LOG.isWarnEnabled()) {
+            LOG.warn("TimeoutEvent received at Sip Subscription Listener");
+        }
+    }
+
+    public void setSipSubscriber(SipSubscriber sipSubscriber) {
+        this.sipSubscriber = sipSubscriber;
+    }
+
+    public SipSubscriber getSipSubscriber() {
+        return sipSubscriber;
+    }
+}

Propchange: camel/trunk/components/camel-sip/src/main/java/org/apache/camel/component/sip/listener/SipSubscriptionListener.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/sip
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/sip?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/sip (added)
+++ camel/trunk/components/camel-sip/src/main/resources/META-INF/services/org/apache/camel/component/sip Mon Aug 23 16:01:03 2010
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+class=org.apache.camel.component.sip.SipComponent

Added: camel/trunk/components/camel-sip/src/main/resources/log4j.properties
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/main/resources/log4j.properties?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/main/resources/log4j.properties (added)
+++ camel/trunk/components/camel-sip/src/main/resources/log4j.properties Mon Aug 23 16:01:03 2010
@@ -0,0 +1,22 @@
+
+#
+# The logging properties used for eclipse testing, We want to see debug output on the console.
+#
+log4j.rootLogger=INFO, out
+
+# uncomment the following line to turn on Camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# uncomment the following line to turn on ActiveMQ debugging
+#log4j.logger.org.apache.activemq=DEBUG
+
+log4j.logger.org.springframework=WARN
+
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+#log4j.appender.out.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+
+log4j.throwableRenderer=org.apache.log4j.EnhancedThrowableRenderer
\ No newline at end of file

Propchange: camel/trunk/components/camel-sip/src/main/resources/log4j.properties
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java?rev=988163&view=auto
==============================================================================
--- camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java (added)
+++ camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java Mon Aug 23 16:01:03 2010
@@ -0,0 +1,86 @@
+/**
+ * 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.sip;
+
+import javax.sip.message.Request;
+
+import org.apache.camel.EndpointInject;
+import org.apache.camel.Produce;
+import org.apache.camel.ProducerTemplate;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.junit.Test;
+
+public class PublishSubscribeTest extends CamelTestSupport {
+    private static final transient Log LOG = LogFactory.getLog(PublishSubscribeTest.class);
+
+    @EndpointInject(uri = "mock:neverland")
+    protected MockEndpoint unreachableEndpoint;
+
+    @EndpointInject(uri = "mock:notification")
+    protected MockEndpoint resultEndpoint;
+
+    @Produce(uri = "direct:start")
+    protected ProducerTemplate producerTemplate;
+    
+    @Test
+    public void testPresenceAgentBasedPubSub() throws Exception {
+        
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Beginning Test ---> testStatefulTransactionalTCPRequestReply()");
+        }
+
+        unreachableEndpoint.expectedMessageCount(0);
+        resultEndpoint.expectedMessageCount(2);
+        
+        producerTemplate.sendBodyAndHeader(
+            "sip://agent@localhost:5152?stackName=client&eventHeaderName=evtHdrName&eventId=evtid&fromUser=user2&fromHost=localhost&fromPort=3534", 
+            "EVENT_A",
+            "REQUEST_METHOD", Request.PUBLISH);         
+        
+        unreachableEndpoint.assertIsSatisfied();
+        resultEndpoint.setResultWaitTime(15000);
+        resultEndpoint.assertIsSatisfied();
+            
+        if (LOG.isDebugEnabled()) {
+            LOG.debug("Completed Test ---> testStatefulTransactionalTCPRequestReply()");
+        }        
+        
+    }   
+    
+    @Override
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {  
+                // Create PresenceAgent
+                from("sip://agent@localhost:5152?stackName=PresenceAgent&presenceAgent=true&eventHeaderName=evtHdrName&eventId=evtid")
+                    .to("mock:neverland");
+                
+                from("sip://johndoe@localhost:5154?stackName=Subscriber&toUser=agent&toHost=localhost&toPort=5152&eventHeaderName=evtHdrName&eventId=evtid")
+                    .to("log:ReceivedEvent?level=DEBUG")
+                    .to("mock:notification");
+                
+            }
+        };
+    }
+    
+
+} 

Propchange: camel/trunk/components/camel-sip/src/test/java/org/apache/camel/component/sip/PublishSubscribeTest.java
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message