1 /*
   2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8172297
  27  * @summary Test that carriage-return and new-line characters
  28  * are preserved in webservice parameters
  29  * @compile ws/HelloWorld.java ws/HelloWorldImpl.java Main.java
  30  * @run testng/othervm Main
  31  */
  32 
  33 import java.io.IOException;
  34 import java.net.ServerSocket;
  35 import java.net.URL;
  36 import java.util.concurrent.CountDownLatch;
  37 
  38 import javax.xml.namespace.QName;
  39 import javax.xml.ws.Endpoint;
  40 import javax.xml.ws.Service;
  41 
  42 import org.testng.Assert;
  43 import org.testng.annotations.Test;
  44 
  45 import ws.HelloWorld;
  46 import ws.HelloWorldImpl;
  47 
  48 public class Main {
  49 
  50     @Test
  51     public void runTest() throws Exception {
  52         //
  53         CountDownLatch serverInitSignal = new CountDownLatch(1);
  54         CountDownLatch testDoneSignal = new CountDownLatch(1);
  55 
  56         WebserviceRunner serverThread = new WebserviceRunner(serverInitSignal, testDoneSignal);
  57         (new Thread(serverThread)).start();
  58 
  59         serverInitSignal.await();
  60 
  61         boolean paramModified = runClientCode(serverThread.getPort());
  62 
  63         testDoneSignal.countDown();
  64 
  65         Assert.assertFalse(paramModified, "WS parameter was modified during round trip.");
  66     }
  67 
  68     /*
  69      * Connects to launched web service endpoint, sends message with CR/NL symbols and
  70      * checks if it was modified during the round trip client/server communication.
  71      */
  72     private boolean runClientCode(int port) throws Exception {
  73         System.out.println("Launching WS client connection on " + port + " port");
  74         URL url = new URL("http://localhost:" + port + "/ws/hello?wsdl");
  75         QName qname = new QName("http://ws/", "HelloWorldImplService");
  76         Service service = Service.create(url, qname);
  77 
  78         HelloWorld hello = (HelloWorld) service.getPort(HelloWorld.class);
  79 
  80         logStringContent("Client input parameter", WS_PARAM_VALUE);
  81 
  82         String response = hello.getHelloWorldAsString(WS_PARAM_VALUE);
  83         logStringContent("Client response parameter", response);
  84 
  85         return !WS_PARAM_VALUE.equals(response);
  86     }
  87 
  88     /*
  89      * Outputs the parameter value with newline and carriage-return symbols
  90      * replaced with #CR and #NL text abbreviations.
  91      */
  92     private static void logStringContent(String description, String parameter) {
  93         String readableContent = parameter.replaceAll("\r", "#CR")
  94                                           .replaceAll("\n", "#NL");
  95         System.out.println(description + ": '" + readableContent + "'");
  96     }
  97 
  98     /* Web service parameter value with newline and carriage-return symbols */
  99     private final static String WS_PARAM_VALUE = "\r\r\n\r\r CarriageReturn and "
 100                                                 +"NewLine \r\n\n Test \r\r\r\r";
 101 
 102     /*
 103      * Web service server thread that publishes WS on vacant port and waits
 104      * for client to finalize testing
 105      */
 106     class WebserviceRunner implements Runnable {
 107         // Latch used to signalize when WS endpoint is initialized
 108         private final CountDownLatch initSignal;
 109         // Latch used to signalize when client completed testing
 110         private final CountDownLatch doneSignal;
 111         // Port where WS endpoint is published
 112         private volatile int port = 0;
 113 
 114         // Constructor
 115         WebserviceRunner(CountDownLatch initSignal, CountDownLatch doneSignal) {
 116             this.initSignal = initSignal;
 117             this.doneSignal = doneSignal;
 118         }
 119 
 120         // Returns port of the published endpoint
 121         public int getPort() {
 122             return port;
 123         }
 124 
 125         /*
 126          * Publish web service on vacant port and waits for the client to
 127          * complete testing.
 128          */
 129         public void run() {
 130             try {
 131                 // Find vacant port number
 132                 ServerSocket ss = new ServerSocket(0);
 133                 port = ss.getLocalPort();
 134                 ss.close();
 135 
 136                 // Publish WebService
 137                 System.out.println("Publishing WebService on " + port + " port");
 138                 Endpoint ep = Endpoint.publish("http://localhost:" + port + "/ws/hello", new HelloWorldImpl());
 139 
 140                 // Notify main thread that WS endpoint is published
 141                 initSignal.countDown();
 142 
 143                 // Wait for main thread to complete testing
 144                 System.out.println("Waiting for done signal from test client.");
 145                 doneSignal.await();
 146 
 147                 // Terminate WS endpoint
 148                 System.out.println("Got done signal from the client. Stopping WS endpoint.");
 149                 ep.stop();
 150             } catch (IOException ioe) {
 151                 System.out.println("Failed to get vacant port number:" + ioe);
 152             } catch (InterruptedException ie) {
 153                 System.out.println("Failed to wait for test completion:" + ie);
 154             }
 155         }
 156     }
 157 }