You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ha...@apache.org on 2012/02/28 06:48:53 UTC

svn commit: r1294468 - in /camel/trunk/components/camel-smpp: ./ src/main/java/org/apache/camel/component/smpp/ src/test/java/org/apache/camel/component/smpp/

Author: hadrian
Date: Tue Feb 28 05:48:53 2012
New Revision: 1294468

URL: http://svn.apache.org/viewvc?rev=1294468&view=rev
Log:
CAMEL-5030. Support for smpp tunnelling through http proxy

Added:
    camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
    camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryTest.java
Removed:
    camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppSSLConnectionFactory.java
    camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppSSLConnectionFactoryTest.java
Modified:
    camel/trunk/components/camel-smpp/pom.xml
    camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
    camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConsumer.java
    camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppProducer.java
    camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java

Modified: camel/trunk/components/camel-smpp/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/pom.xml?rev=1294468&r1=1294467&r2=1294468&view=diff
==============================================================================
--- camel/trunk/components/camel-smpp/pom.xml (original)
+++ camel/trunk/components/camel-smpp/pom.xml Tue Feb 28 05:48:53 2012
@@ -44,6 +44,11 @@
             <artifactId>org.apache.servicemix.bundles.jsmpp</artifactId>
             <version>${jsmpp-version}</version>
         </dependency>
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>${commons-codec-version}</version>
+        </dependency>
 
         <!-- testing -->
         <dependency>
@@ -72,7 +77,6 @@
             <artifactId>slf4j-log4j12</artifactId>
             <scope>test</scope>
         </dependency>
-
     </dependencies>
 
 </project>

Modified: camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java?rev=1294468&r1=1294467&r2=1294468&view=diff
==============================================================================
--- camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java (original)
+++ camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConfiguration.java Tue Feb 28 05:48:53 2012
@@ -59,6 +59,10 @@ public class SmppConfiguration implement
     private long initialReconnectDelay = 5000;
     private long reconnectDelay = 5000;
     private boolean lazySessionCreation;
+    private String httpProxyHost;
+    private Integer httpProxyPort = Integer.valueOf(3128);
+    private String httpProxyUsername;
+    private String httpProxyPassword;
 
     /**
      * A POJO which contains all necessary configuration parameters for the SMPP connection
@@ -289,6 +293,38 @@ public class SmppConfiguration implement
     public void setLazySessionCreation(boolean lazySessionCreation) {
         this.lazySessionCreation = lazySessionCreation;
     }
+    
+    public String getHttpProxyHost() {
+        return httpProxyHost;
+    }
+    
+    public void setHttpProxyHost(String httpProxyHost) {
+        this.httpProxyHost = httpProxyHost;
+    }
+    
+    public Integer getHttpProxyPort() {
+        return httpProxyPort;
+    }
+    
+    public void setHttpProxyPort(Integer httpProxyPort) {
+        this.httpProxyPort = httpProxyPort;
+    }
+    
+    public String getHttpProxyUsername() {
+        return httpProxyUsername;
+    }
+    
+    public void setHttpProxyUsername(String httpProxyUsername) {
+        this.httpProxyUsername = httpProxyUsername;
+    }
+    
+    public String getHttpProxyPassword() {
+        return httpProxyPassword;
+    }
+    
+    public void setHttpProxyPassword(String httpProxyPassword) {
+        this.httpProxyPassword = httpProxyPassword;
+    }
 
     @Override
     public String toString() {
@@ -318,6 +354,10 @@ public class SmppConfiguration implement
             + ", initialReconnectDelay=" + initialReconnectDelay
             + ", reconnectDelay=" + reconnectDelay
             + ", lazySessionCreation=" + lazySessionCreation
+            + ", httpProxyHost=" + httpProxyHost
+            + ", httpProxyPort=" + httpProxyPort
+            + ", httpProxyUsername=" + httpProxyUsername
+            + ", httpProxyPassword=" + httpProxyPassword
             + "]";
     }
 }

Added: camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java?rev=1294468&view=auto
==============================================================================
--- camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java (added)
+++ camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConnectionFactory.java Tue Feb 28 05:48:53 2012
@@ -0,0 +1,169 @@
+/**
+ * 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.
+ */
+
+/**
+ * The connectProxy() method implementation is inspired from 
+ * com.jcraft.jsch.ProxyHTTP available under a BSD style license (below).
+ * 
+ * Copyright (c) 2002-2010 ymnk, JCraft,Inc. All rights reserved.
+
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the distribution.
+
+ * 3. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ * INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+package org.apache.camel.component.smpp;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.camel.RuntimeCamelException;
+import org.apache.commons.codec.binary.Base64;
+import org.jsmpp.session.connection.Connection;
+import org.jsmpp.session.connection.ConnectionFactory;
+import org.jsmpp.session.connection.socket.SocketConnection;
+
+/**
+ * A Jsmpp ConnectionFactory that creates SSL Sockets.
+ * 
+ * @version 
+ */
+public final class SmppConnectionFactory implements ConnectionFactory {
+    private SmppConfiguration config;
+
+    private SmppConnectionFactory(SmppConfiguration config) {
+        this.config = config;
+    }
+    
+    public static SmppConnectionFactory getInstance(SmppConfiguration config) {
+        return new SmppConnectionFactory(config);
+    }    
+
+    public Connection createConnection(String host, int port) throws IOException {
+        try {
+            Socket socket;
+            SocketFactory socketFactory;
+            socketFactory = config.getUsingSSL() ? SSLSocketFactory.getDefault() : SocketFactory.getDefault();
+            if (config.getHttpProxyHost() != null) {
+                socket = socketFactory.createSocket(config.getHttpProxyHost(), config.getHttpProxyPort());
+                connectProxy(host, port, socket);
+            } else {
+                socket = socketFactory.createSocket(host, port);
+            }
+            return new SocketConnection(socket);
+
+        } catch (Exception e) {
+            throw new IOException(e.getMessage());
+        }
+    }
+
+    private void connectProxy(String host, int port, Socket socket) throws IOException {
+        try {
+            OutputStream out = socket.getOutputStream();
+            InputStream in = socket.getInputStream();
+
+            String connectString = "CONNECT " + host + ":" + port + " HTTP/1.0\r\n";
+            out.write(connectString.getBytes());
+
+            String username = config.getHttpProxyUsername();
+            String password = config.getHttpProxyPassword();
+            
+            if (username != null && password != null) {
+                String usernamePassword = username + ":" + password;
+                byte[] code = Base64.encodeBase64(usernamePassword.getBytes());
+                out.write("Proxy-Authorization: Basic ".getBytes());
+                out.write(code);
+                out.write("\r\n".getBytes());
+            }
+            
+            out.write("\r\n".getBytes());
+            out.flush();
+
+            int ch = 0;
+
+            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+            String response = reader.readLine();
+            if (response == null) {
+                throw new RuntimeCamelException("Empty response to CONNECT request to host " + host + ":" + port);
+            }
+            String reason = "Unknown reason";
+            int code = -1;
+            try {
+                ch = response.indexOf(' ');
+                int bar = response.indexOf(' ', ch + 1);
+                code = Integer.parseInt(response.substring(ch + 1, bar));
+                reason = response.substring(bar + 1);
+            } catch (NumberFormatException e) {
+                throw new RuntimeCamelException("Invalid response to CONNECT request to host " + host + ":" + port 
+                    + " - cannot parse code from response string: " + response);
+            }
+            if (code != 200) {
+                throw new RuntimeCamelException("Proxy error: " + reason);
+            }
+
+            // read until empty line
+            for (; response.length() > 0;) {
+                response = reader.readLine();
+                if (response == null) {
+                    throw new RuntimeCamelException("Proxy error: reached end of stream");
+                }
+            }
+        } catch (RuntimeException re) {
+            closeSocket(socket);
+            throw re;
+        } catch (Exception e) {
+            closeSocket(socket);
+            throw new RuntimeException("SmppConnectionFactory: " + e.getMessage());
+        }
+    }
+
+    private static void closeSocket(Socket s) {
+        if (s != null) {
+            try {
+                s.close();
+            } catch (IOException e) {
+                // ignore
+            }
+        }
+    }
+}
\ No newline at end of file

Modified: camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConsumer.java?rev=1294468&r1=1294467&r2=1294468&view=diff
==============================================================================
--- camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConsumer.java (original)
+++ camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConsumer.java Tue Feb 28 05:48:53 2012
@@ -102,13 +102,9 @@ public class SmppConsumer extends Defaul
      * @return the SMPPSession
      */
     SMPPSession createSMPPSession() {
-        if (configuration.getUsingSSL()) {
-            return new SMPPSession(new SynchronizedPDUSender(new DefaultPDUSender(
-                    new DefaultComposer())), new DefaultPDUReader(), SmppSSLConnectionFactory
-                    .getInstance());
-        } else {
-            return new SMPPSession();
-        }
+        return new SMPPSession(new SynchronizedPDUSender(new DefaultPDUSender(
+                    new DefaultComposer())), new DefaultPDUReader(), SmppConnectionFactory
+                    .getInstance(configuration));
     }
 
     @Override

Modified: camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppProducer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppProducer.java?rev=1294468&r1=1294467&r2=1294468&view=diff
==============================================================================
--- camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppProducer.java (original)
+++ camel/trunk/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppProducer.java Tue Feb 28 05:48:53 2012
@@ -106,12 +106,9 @@ public class SmppProducer extends Defaul
      * @return the SMPPSession
      */
     SMPPSession createSMPPSession() {
-        if (configuration.getUsingSSL()) {
-            return new SMPPSession(new SynchronizedPDUSender(new DefaultPDUSender(new DefaultComposer())),
-                                   new DefaultPDUReader(), SmppSSLConnectionFactory.getInstance());
-        } else {
-            return new SMPPSession();
-        }
+        return new SMPPSession(new SynchronizedPDUSender(new DefaultPDUSender(
+                new DefaultComposer())), new DefaultPDUReader(), SmppConnectionFactory
+                .getInstance(configuration));
     }
 
     public void process(Exchange exchange) throws Exception {

Modified: camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java?rev=1294468&r1=1294467&r2=1294468&view=diff
==============================================================================
--- camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java (original)
+++ camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConfigurationTest.java Tue Feb 28 05:48:53 2012
@@ -67,6 +67,10 @@ public class SmppConfigurationTest {
         assertEquals(false, configuration.getUsingSSL());
         assertEquals(5000, configuration.getInitialReconnectDelay());
         assertEquals(5000, configuration.getReconnectDelay());
+        assertEquals(null, configuration.getHttpProxyHost());
+        assertEquals(new Integer(3128), configuration.getHttpProxyPort());
+        assertEquals(null, configuration.getHttpProxyUsername());
+        assertEquals(null, configuration.getHttpProxyPassword());
     }
     
     @Test
@@ -97,6 +101,10 @@ public class SmppConfigurationTest {
         assertEquals(true, configuration.getUsingSSL());
         assertEquals(5001, configuration.getInitialReconnectDelay());
         assertEquals(5002, configuration.getReconnectDelay());
+        assertEquals("127.0.0.1", configuration.getHttpProxyHost());
+        assertEquals(new Integer(3129), configuration.getHttpProxyPort());
+        assertEquals("user", configuration.getHttpProxyUsername());
+        assertEquals("secret", configuration.getHttpProxyPassword());
     }
 
     @Test
@@ -137,6 +145,10 @@ public class SmppConfigurationTest {
         assertEquals(config.getUsingSSL(), configuration.getUsingSSL());
         assertEquals(config.getInitialReconnectDelay(), configuration.getInitialReconnectDelay());
         assertEquals(config.getReconnectDelay(), configuration.getReconnectDelay());
+        assertEquals(config.getHttpProxyHost(), configuration.getHttpProxyHost());
+        assertEquals(config.getHttpProxyPort(), configuration.getHttpProxyPort());
+        assertEquals(config.getHttpProxyUsername(), configuration.getHttpProxyUsername());
+        assertEquals(config.getHttpProxyPassword(), configuration.getHttpProxyPassword());
         
     }
     
@@ -168,7 +180,11 @@ public class SmppConfigurationTest {
                 + "numberingPlanIndicator=0, "
                 + "initialReconnectDelay=5000, "
                 + "reconnectDelay=5000, "
-                + "lazySessionCreation=false]";
+                + "lazySessionCreation=false, "
+                + "httpProxyHost=null, "
+                + "httpProxyPort=3128, "
+                + "httpProxyUsername=null, "
+                + "httpProxyPassword=null]";
         assertEquals(expected, configuration.toString());
     }
 
@@ -197,5 +213,9 @@ public class SmppConfigurationTest {
         config.setUsingSSL(true);
         config.setInitialReconnectDelay(5001);
         config.setReconnectDelay(5002);
+        config.setHttpProxyHost("127.0.0.1");
+        config.setHttpProxyPort(new Integer(3129));
+        config.setHttpProxyUsername("user");
+        config.setHttpProxyPassword("secret");
     }
 }
\ No newline at end of file

Added: camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryTest.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryTest.java?rev=1294468&view=auto
==============================================================================
--- camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryTest.java (added)
+++ camel/trunk/components/camel-smpp/src/test/java/org/apache/camel/component/smpp/SmppConnectionFactoryTest.java Tue Feb 28 05:48:53 2012
@@ -0,0 +1,89 @@
+/**
+ * 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.smpp;
+
+import java.io.IOException;
+
+import org.jsmpp.session.connection.Connection;
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * JUnit test class for <code>org.apache.camel.component.smpp.SmppConnectionFactory</code>
+ * 
+ * @version 
+ */
+public class SmppConnectionFactoryTest {
+
+    @Test
+    @Ignore("Must be manually tested")
+    public void createConnection() throws IOException {
+        SmppConfiguration configuration = new SmppConfiguration();
+        SmppConnectionFactory factory = SmppConnectionFactory.getInstance(configuration);
+        Connection connection = factory.createConnection("localhost", 2775);
+
+        try {
+            Assert.assertNotNull(connection);
+            Assert.assertTrue(connection.isOpen());            
+        } finally {
+            if (connection != null) {
+                connection.close();
+            }
+        }
+    }
+    
+    @Test
+    @Ignore("Must be manually tested")
+    public void createConnectionWithProxyHost() throws IOException {
+        SmppConfiguration configuration = new SmppConfiguration();
+        configuration.setHttpProxyHost("localhost");
+        configuration.setHttpProxyPort(new Integer(3128));
+        SmppConnectionFactory factory = SmppConnectionFactory.getInstance(configuration);
+        Connection connection = factory.createConnection("localhost", 2775);
+
+        try {
+            Assert.assertNotNull(connection);
+            Assert.assertTrue(connection.isOpen());
+        } finally {
+            if (connection != null) {
+                connection.close();
+            }
+        }
+    }
+    
+    @Test
+    @Ignore("Must be manually tested")
+    public void createConnectionWithProxyUsername() throws IOException {
+        SmppConfiguration configuration = new SmppConfiguration();
+        configuration.setHttpProxyHost("localhost");
+        configuration.setHttpProxyPort(new Integer(3128));
+        configuration.setHttpProxyUsername("user");
+        configuration.setHttpProxyPassword("secret");
+        SmppConnectionFactory factory = SmppConnectionFactory.getInstance(configuration);
+        Connection connection = factory.createConnection("localhost", 2775);
+
+        try {
+            Assert.assertNotNull(connection);
+            Assert.assertTrue(connection.isOpen());            
+        } finally {
+            if (connection != null) {
+                connection.close();
+            }
+        }
+    }     
+}
\ No newline at end of file