You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ol...@apache.org on 2012/03/17 00:35:32 UTC

svn commit: r1301824 - in /tomcat/maven-plugin/trunk: common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/ common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/ common-tomcat-maven-plugin/src/test/resourc...

Author: olamy
Date: Fri Mar 16 23:35:32 2012
New Revision: 1301824

URL: http://svn.apache.org/viewvc?rev=1301824&view=rev
Log:
[MTOMCAT-116] handle redirect response when deploying a war

Modified:
    tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
    tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java
    tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt
    tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java
    tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java

Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java?rev=1301824&r1=1301823&r2=1301824&view=diff
==============================================================================
--- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java (original)
+++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java Fri Mar 16 23:35:32 2012
@@ -22,8 +22,10 @@ package org.apache.tomcat.maven.common.d
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
+import org.apache.http.Header;
 import org.apache.http.HttpHost;
 import org.apache.http.HttpResponse;
+import org.apache.http.HttpStatus;
 import org.apache.http.auth.AuthScope;
 import org.apache.http.auth.Credentials;
 import org.apache.http.auth.UsernamePasswordCredentials;
@@ -36,10 +38,11 @@ import org.apache.http.entity.AbstractHt
 import org.apache.http.impl.auth.BasicScheme;
 import org.apache.http.impl.client.BasicAuthCache;
 import org.apache.http.impl.client.DefaultHttpClient;
-import org.apache.http.impl.conn.BasicClientConnectionManager;
+import org.apache.http.impl.conn.PoolingClientConnectionManager;
 import org.apache.http.protocol.BasicHttpContext;
-import org.apache.maven.plugin.logging.Log;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
@@ -162,7 +165,9 @@ public class TomcatManager
         this.password = password;
         this.charset = charset;
 
-        this.httpClient = new DefaultHttpClient( new BasicClientConnectionManager() );
+        PoolingClientConnectionManager poolingClientConnectionManager = new PoolingClientConnectionManager();
+        poolingClientConnectionManager.setMaxTotal( 5 );
+        this.httpClient = new DefaultHttpClient( poolingClientConnectionManager );
         if ( StringUtils.isNotEmpty( username ) && StringUtils.isNotEmpty( password ) )
         {
             Credentials creds = new UsernamePasswordCredentials( username, password );
@@ -305,7 +310,7 @@ public class TomcatManager
      * @throws TomcatManagerException if the Tomcat manager request fails
      * @throws IOException            if an i/o error occurs
      */
-    public TomcatManagerResponse deploy( String path, InputStream war )
+    public TomcatManagerResponse deploy( String path, File war )
         throws TomcatManagerException, IOException
     {
         return deploy( path, war, false );
@@ -322,7 +327,7 @@ public class TomcatManager
      * @throws TomcatManagerException if the Tomcat manager request fails
      * @throws IOException            if an i/o error occurs
      */
-    public TomcatManagerResponse deploy( String path, InputStream war, boolean update )
+    public TomcatManagerResponse deploy( String path, File war, boolean update )
         throws TomcatManagerException, IOException
     {
         return deploy( path, war, update, null );
@@ -340,7 +345,7 @@ public class TomcatManager
      * @throws TomcatManagerException if the Tomcat manager request fails
      * @throws IOException            if an i/o error occurs
      */
-    public TomcatManagerResponse deploy( String path, InputStream war, boolean update, String tag )
+    public TomcatManagerResponse deploy( String path, File war, boolean update, String tag )
         throws TomcatManagerException, IOException
     {
         return deployImpl( path, null, null, war, update, tag );
@@ -357,7 +362,7 @@ public class TomcatManager
      * @throws IOException
      * @since 2.0
      */
-    public TomcatManagerResponse deploy( String path, InputStream war, boolean update, String tag, long length )
+    public TomcatManagerResponse deploy( String path, File war, boolean update, String tag, long length )
         throws TomcatManagerException, IOException
     {
         return deployImpl( path, null, null, war, update, tag, length );
@@ -631,8 +636,7 @@ public class TomcatManager
     // Private Methods
     // ----------------------------------------------------------------------
 
-    private TomcatManagerResponse deployImpl( String path, URL config, URL war, InputStream data, boolean update,
-                                              String tag )
+    private TomcatManagerResponse deployImpl( String path, URL config, URL war, File data, boolean update, String tag )
         throws TomcatManagerException, IOException
     {
         return deployImpl( path, config, war, data, update, tag, -1 );
@@ -644,15 +648,15 @@ public class TomcatManager
      * @param path   the webapp context path to deploy to
      * @param config the URL of the context XML configuration to deploy, or null for none
      * @param war    the URL of the WAR to deploy, or null to use <code>data</code>
-     * @param data   an input stream to the WAR to deploy, or null to use <code>war</code>
+     * @param data   WAR file to deploy, or null to use <code>war</code>
      * @param update whether to first undeploy the webapp if it already exists
      * @param tag    the tag name to use
      * @return the Tomcat manager response
      * @throws TomcatManagerException if the Tomcat manager request fails
      * @throws IOException            if an i/o error occurs
      */
-    private TomcatManagerResponse deployImpl( String path, URL config, URL war, InputStream data, boolean update,
-                                              String tag, long length )
+    private TomcatManagerResponse deployImpl( String path, URL config, URL war, File data, boolean update, String tag,
+                                              long length )
         throws TomcatManagerException, IOException
     {
         StringBuilder buffer = new StringBuilder( "/deploy" );
@@ -686,12 +690,12 @@ public class TomcatManager
      * Invokes Tomcat manager with the specified command and content data.
      *
      * @param path the Tomcat manager command to invoke
-     * @param data an input stream to the content data
+     * @param data file to deploy
      * @return the Tomcat manager response
      * @throws TomcatManagerException if the Tomcat manager request fails
      * @throws IOException            if an i/o error occurs
      */
-    protected TomcatManagerResponse invoke( String path, InputStream data, long length )
+    protected TomcatManagerResponse invoke( String path, File data, long length )
         throws TomcatManagerException, IOException
     {
 
@@ -717,12 +721,38 @@ public class TomcatManager
 
         HttpResponse response = httpClient.execute( httpRequestBase, localContext );
 
+        int statusCode = response.getStatusLine().getStatusCode();
+
+        switch ( statusCode )
+        {
+            // Success Codes
+            case HttpStatus.SC_OK: // 200
+            case HttpStatus.SC_CREATED: // 201
+            case HttpStatus.SC_ACCEPTED: // 202
+                break;
+            // handle all redirect even if http specs says " the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user"
+            case HttpStatus.SC_MOVED_PERMANENTLY: // 301
+            case HttpStatus.SC_MOVED_TEMPORARILY: // 302
+            case HttpStatus.SC_SEE_OTHER: // 303
+                String relocateUrl = calculateRelocatedUrl( response );
+                this.url = new URL( relocateUrl );
+                return invoke( path, data, length );
+        }
+
         return new TomcatManagerResponse().setStatusCode( response.getStatusLine().getStatusCode() ).setReasonPhrase(
             response.getStatusLine().getReasonPhrase() ).setHttpResponseBody(
             IOUtils.toString( response.getEntity().getContent() ) );
 
     }
 
+    protected String calculateRelocatedUrl( HttpResponse response )
+    {
+        Header locationHeader = response.getFirstHeader( "Location" );
+        String locationField = locationHeader.getValue();
+        // is it a relative Location or a full ?
+        return locationField.startsWith( "http" ) ? locationField : url.toString() + '/' + locationField;
+    }
+
 
     /**
      * Gets the HTTP Basic Authorization header value for the supplied username and password.
@@ -748,7 +778,7 @@ public class TomcatManager
 
         private final static int BUFFER_SIZE = 2048;
 
-        private InputStream stream;
+        private File file;
 
         PrintStream out = System.out;
 
@@ -760,28 +790,28 @@ public class TomcatManager
 
         private long startTime;
 
-        private RequestEntityImplementation( final InputStream stream, long length, String url )
+        private RequestEntityImplementation( final File file, long length, String url )
         {
-            this.stream = stream;
+            this.file = file;
             this.length = length;
             this.url = url;
         }
 
         public long getContentLength()
         {
-            return length >= 0 ? length : -1;
+            return length >= 0 ? length : ( file.length() >= 0 ? file.length() : -1 );
         }
 
 
         public InputStream getContent()
             throws IOException, IllegalStateException
         {
-            return this.stream;
+            return new FileInputStream( this.file );
         }
 
         public boolean isRepeatable()
         {
-            return false;
+            return true;
         }
 
 
@@ -793,11 +823,13 @@ public class TomcatManager
             {
                 throw new IllegalArgumentException( "Output stream may not be null" );
             }
+            FileInputStream stream = new FileInputStream( this.file );
             transferInitiated( this.url );
             this.startTime = System.currentTimeMillis();
             try
             {
                 byte[] buffer = new byte[BUFFER_SIZE];
+
                 int l;
                 if ( this.length < 0 )
                 {

Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java
URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java?rev=1301824&r1=1301823&r2=1301824&view=diff
==============================================================================
--- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java (original)
+++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/java/org/apache/tomcat/maven/common/TomcatManagerTest.java Fri Mar 16 23:35:32 2012
@@ -23,6 +23,7 @@ import org.apache.catalina.Context;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.commons.io.IOUtils;
 import org.apache.tomcat.maven.common.deployer.TomcatManager;
+import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse;
 
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
@@ -46,10 +47,16 @@ public class TomcatManagerTest
 
     Tomcat tomcat;
 
+    Tomcat redirectTomcat;
+
     UploadServlet uploadServlet;
 
+    RedirectServlet redirectServlet;
+
     int port;
 
+    int redirectPort;
+
     public static String getBasedir()
     {
         return System.getProperty( "basedir" );
@@ -74,6 +81,18 @@ public class TomcatManagerTest
         port = tomcat.getConnector().getLocalPort();
 
         System.out.println( "Tomcat started on port:" + port );
+
+        redirectTomcat = new Tomcat();
+        redirectTomcat.setBaseDir( System.getProperty( "java.io.tmpdir" ) );
+        redirectTomcat.setPort( 0 );
+        context = redirectTomcat.addContext( "", System.getProperty( "java.io.tmpdir" ) );
+        redirectServlet = new RedirectServlet();
+        redirectTomcat.addServlet( context, "foo", redirectServlet );
+        context.addServletMapping( "/*", "foo" );
+        redirectTomcat.start();
+        redirectPort = redirectTomcat.getConnector().getLocalPort();
+
+        System.out.println( "redirect Tomcat started on port:" + redirectPort );
     }
 
     @Override
@@ -88,13 +107,82 @@ public class TomcatManagerTest
     public void testDeployWar()
         throws Exception
     {
+        uploadServlet.uploadedResources.clear();
         TomcatManager tomcatManager = new TomcatManager( new URL( "http://localhost:" + this.port + "/foo/bar" ) );
-        tomcatManager.deploy( "foo", new FileInputStream( new File( getBasedir(), "src/test/resources/test.txt" ) ) );
-        StringWriter sw = new StringWriter();
+        TomcatManagerResponse response =
+            tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) );
+
+        assertEquals( 200, response.getStatusCode() );
+
         assertEquals( 1, uploadServlet.uploadedResources.size() );
+        assertEquals( "/foo/bar/deploy", uploadServlet.uploadedResources.get( 0 ).requestUri );
+        FileInputStream fileInputStream = new FileInputStream( uploadServlet.uploadedResources.get( 0 ).uploadedFile );
+        try
+        {
+            StringWriter sw = new StringWriter();
+            IOUtils.copy( fileInputStream, sw );
+            assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) );
+        }
+        finally
+        {
+            fileInputStream.close();
+        }
+    }
+
+    public void testDeployWarWithRedirect()
+        throws Exception
+    {
+        uploadServlet.uploadedResources.clear();
+        TomcatManager tomcatManager =
+            new TomcatManager( new URL( "http://localhost:" + this.redirectPort + "/foo/bar" ) );
+        redirectServlet.redirectPath = "http://localhost:" + this.port + "/foo/bar/redirected";
+        TomcatManagerResponse response =
+            tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) );
+
+        assertEquals( 200, response.getStatusCode() );
+
+        assertEquals( "no request to redirect servlet", 1, redirectServlet.uploadedResources.size() );
+        assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri );
+        assertEquals( "no  redirected request to upload servlet", 1, uploadServlet.uploadedResources.size() );
+
+        assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri );
+
         FileInputStream fileInputStream = new FileInputStream( uploadServlet.uploadedResources.get( 0 ).uploadedFile );
         try
         {
+            StringWriter sw = new StringWriter();
+            IOUtils.copy( fileInputStream, sw );
+            assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) );
+        }
+        finally
+        {
+            fileInputStream.close();
+        }
+    }
+
+    public void testDeployWarWithRedirectRelative()
+        throws Exception
+    {
+        uploadServlet.uploadedResources.clear();
+        TomcatManager tomcatManager =
+            new TomcatManager( new URL( "http://localhost:" + this.redirectPort + "/foo/bar" ) );
+        redirectServlet.redirectPath = "redirectrelative/foo";
+        TomcatManagerResponse response =
+            tomcatManager.deploy( "foo", new File( getBasedir(), "src/test/resources/test.txt" ) );
+
+        assertEquals( 200, response.getStatusCode() );
+
+        assertEquals( "no request to redirect servlet", 2, redirectServlet.uploadedResources.size() );
+        assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri );
+        assertEquals( "found redirected request to upload servlet", 0, uploadServlet.uploadedResources.size() );
+
+        assertEquals( "/foo/bar/deploy", redirectServlet.uploadedResources.get( 0 ).requestUri );
+
+        FileInputStream fileInputStream =
+            new FileInputStream( redirectServlet.uploadedResources.get( 1 ).uploadedFile );
+        try
+        {
+            StringWriter sw = new StringWriter();
             IOUtils.copy( fileInputStream, sw );
             assertTrue( sw.toString().contains( "Apache Tomcat rocks!!" ) );
         }
@@ -132,10 +220,37 @@ public class TomcatManagerTest
             throws ServletException, IOException
         {
             System.out.println( "put ok:" + req.getRequestURI() );
-            super.doPut( req, resp );
             File file = File.createTempFile( "tomcat-unit-test", "tmp" );
             uploadedResources.add( new UploadedResource( req.getRequestURI(), file ) );
             IOUtils.copy( req.getInputStream(), new FileOutputStream( file ) );
         }
     }
+
+    public class RedirectServlet
+        extends HttpServlet
+    {
+        int redirectPort = 0;
+
+        String redirectPath;
+
+        public List<UploadedResource> uploadedResources = new ArrayList<UploadedResource>();
+
+        @Override
+        protected void doPut( HttpServletRequest req, HttpServletResponse resp )
+            throws ServletException, IOException
+        {
+            System.out.println( "RedirectServlet put ok:" + req.getRequestURI() );
+            if ( req.getRequestURI().contains( "redirectrelative" ) )
+            {
+                File file = File.createTempFile( "tomcat-unit-test", "tmp" );
+                uploadedResources.add( new UploadedResource( req.getRequestURI(), file ) );
+                IOUtils.copy( req.getInputStream(), new FileOutputStream( file ) );
+                return;
+            }
+            uploadedResources.add( new UploadedResource( req.getRequestURI(), null ) );
+            String redirectUri =
+                redirectPort > 0 ? "http://localhost:" + redirectPort + "/" + redirectPath : redirectPath;
+            resp.sendRedirect( redirectUri );
+        }
+    }
 }

Modified: tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt
URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt?rev=1301824&r1=1301823&r2=1301824&view=diff
==============================================================================
--- tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt (original)
+++ tomcat/maven-plugin/trunk/common-tomcat-maven-plugin/src/test/resources/test.txt Fri Mar 16 23:35:32 2012
@@ -1,2 +1,21 @@
+/*
+ * 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.
+ */
+
 Apache Tomcat rocks!!
 hey Apache Maven rocks too :P
\ No newline at end of file

Modified: tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java
URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java?rev=1301824&r1=1301823&r2=1301824&view=diff
==============================================================================
--- tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java (original)
+++ tomcat/maven-plugin/trunk/tomcat6-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat6/AbstractDeployWarMojo.java Fri Mar 16 23:35:32 2012
@@ -23,7 +23,6 @@ import org.apache.maven.plugin.MojoExecu
 import org.apache.tomcat.maven.common.deployer.TomcatManagerException;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 
 /**
@@ -84,7 +83,6 @@ public class AbstractDeployWarMojo
 
         getLog().info( messagesProvider.getMessage( "AbstractDeployMojo.deployingWar", getDeployedURL() ) );
 
-        log( getManager().deploy( getPath(), new FileInputStream( warFile ), isUpdate(), getTag(),
-                                  warFile.length() ).getHttpResponseBody() );
+        log( getManager().deploy( getPath(), warFile, isUpdate(), getTag(), warFile.length() ).getHttpResponseBody() );
     }
 }

Modified: tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java
URL: http://svn.apache.org/viewvc/tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java?rev=1301824&r1=1301823&r2=1301824&view=diff
==============================================================================
--- tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java (original)
+++ tomcat/maven-plugin/trunk/tomcat7-maven-plugin/src/main/java/org/apache/tomcat/maven/plugin/tomcat7/deploy/AbstractDeployWarMojo.java Fri Mar 16 23:35:32 2012
@@ -24,7 +24,6 @@ import org.apache.tomcat.maven.common.de
 import org.apache.tomcat.maven.common.deployer.TomcatManagerResponse;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.IOException;
 
 /**
@@ -86,7 +85,7 @@ public class AbstractDeployWarMojo
         getLog().info( messagesProvider.getMessage( "AbstractDeployMojo.deployingWar", getDeployedURL() ) );
 
         TomcatManagerResponse tomcatManagerResponse =
-            getManager().deploy( getPath(), new FileInputStream( warFile ), isUpdate(), getTag(), warFile.length() );
+            getManager().deploy( getPath(), warFile, isUpdate(), getTag(), warFile.length() );
 
         getLog().info( "tomcatManager status code:" + tomcatManagerResponse.getStatusCode() + ", ReasonPhrase:"
                            + tomcatManagerResponse.getReasonPhrase() );



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org