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 8087112 27 * @library /lib/testlibrary/ 28 * @build jdk.testlibrary.SimpleSSLContext 29 * @compile ../../../com/sun/net/httpserver/LogFilter.java 30 * @compile ../../../com/sun/net/httpserver/FileServerHandler.java 31 * @run main/othervm ManyRequests 32 * @summary Send a large number of requests asynchronously 33 */ 34 35 //package javaapplication16; 36 37 import com.sun.net.httpserver.HttpsConfigurator; 38 import com.sun.net.httpserver.HttpsServer; 39 import java.io.IOException; 40 import java.io.UncheckedIOException; 41 import java.net.http.HttpClient; 42 import java.net.http.HttpRequest; 43 import java.net.http.HttpResponse; 44 import java.net.InetSocketAddress; 45 import java.net.URI; 46 import java.util.Arrays; 47 import java.util.HashMap; 48 import java.util.LinkedList; 49 import java.util.Random; 50 import java.util.concurrent.CompletableFuture; 51 import javax.net.ssl.SSLContext; 52 import jdk.testlibrary.SimpleSSLContext; 53 54 public class ManyRequests { 55 56 public static void main(String[] args) throws Exception { 57 SSLContext ctx = new SimpleSSLContext().get(); 58 59 InetSocketAddress addr = new InetSocketAddress(0); 60 HttpsServer server = HttpsServer.create(addr, 0); 61 server.setHttpsConfigurator(new HttpsConfigurator(ctx)); 62 63 HttpClient client = HttpClient.create() 64 .sslContext(ctx) 65 .build(); 66 try { 67 test(server, client); 68 System.out.println("OK"); 69 } finally { 70 server.stop(0); 71 client.executorService().shutdownNow(); 72 } 73 } 74 75 static final int REQUESTS = 1000; 76 77 static void test(HttpsServer server, HttpClient client) throws Exception { 78 int port = server.getAddress().getPort(); 79 URI uri = new URI("https://127.0.0.1:" + port + "/foo/x"); 80 server.createContext("/foo", new EchoHandler()); 81 server.start(); 82 83 RequestLimiter limiter = new RequestLimiter(40); 84 Random rand = new Random(); 85 CompletableFuture<Void>[] results = new CompletableFuture[REQUESTS]; 86 HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); 87 88 for (int i=0; i<REQUESTS; i++) { 89 byte[] buf = new byte[i+1]; // different size bodies 90 rand.nextBytes(buf); 91 HttpRequest r = client.request(uri) 92 .body(HttpRequest.fromByteArray(buf)) 93 .POST(); 94 bodies.put(r, buf); 95 96 results[i] = 97 limiter.whenOkToSend() 98 .thenCompose((v) -> r.responseAsync()) 99 .thenCompose((resp) -> { 100 limiter.requestComplete(); 101 if (resp.statusCode() != 200) { 102 resp.bodyAsync(HttpResponse.ignoreBody()); 103 String s = "Expected 200, got: " + resp.statusCode(); 104 return completedWithIOException(s); 105 } 106 return resp.bodyAsync(HttpResponse.asByteArray()) 107 .thenApply((b) -> new Pair<>(resp, b)); 108 }) 109 .thenAccept((pair) -> { 110 HttpRequest request = pair.t.request(); 111 byte[] requestBody = bodies.get(request); 112 check(Arrays.equals(requestBody, pair.u), 113 "bodies not equal"); 114 115 }); 116 } 117 // wait for them all to complete and throw exception in case of error 118 CompletableFuture.allOf(results).join(); 119 } 120 121 static <T> CompletableFuture<T> completedWithIOException(String message) { 122 CompletableFuture<T> cf = new CompletableFuture<>(); 123 cf.completeExceptionally(new IOException(message)); 124 return cf; 125 } 126 127 static final class Pair<T,U> { 128 Pair(T t, U u) { 129 this.t = t; this.u = u; 130 } 131 T t; 132 U u; 133 } 134 135 /** 136 * A simple limiter for controlling the number of requests to be run in 137 * parallel whenOkToSend() is called which returns a CF<Void> that allows 138 * each individual request to proceed, or block temporarily (blocking occurs 139 * on the waiters list here. As each request actually completes 140 * requestComplete() is called to notify this object, and allow some 141 * requests to continue. 142 */ 143 static class RequestLimiter { 144 175 blocked = true; 176 CompletableFuture<Void> r = new CompletableFuture<>(); 177 waiters.add(r); 178 return r; 179 } else { 180 number++; 181 return COMPLETED_FUTURE; 182 } 183 } 184 } 185 186 static void check(boolean cond, Object... msg) { 187 if (cond) 188 return; 189 StringBuilder sb = new StringBuilder(); 190 for (Object o : msg) 191 sb.append(o); 192 throw new RuntimeException(sb.toString()); 193 } 194 } | 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 8087112 27 * @library /lib/testlibrary/ / 28 * @build jdk.testlibrary.SimpleSSLContext EchoHandler 29 * @compile ../../../com/sun/net/httpserver/LogFilter.java 30 * @compile ../../../com/sun/net/httpserver/FileServerHandler.java 31 * @run main/othervm/timeout=40 -Djava.net.http.HttpClient.log=ssl ManyRequests 32 * @summary Send a large number of requests asynchronously 33 */ 34 35 //package javaapplication16; 36 37 import com.sun.net.httpserver.*; 38 import java.io.IOException; 39 import java.io.UncheckedIOException; 40 import java.net.http.HttpClient; 41 import java.net.http.HttpRequest; 42 import java.net.http.HttpResponse; 43 import java.net.InetSocketAddress; 44 import java.net.URI; 45 import java.util.Arrays; 46 import java.util.HashMap; 47 import java.util.LinkedList; 48 import java.util.Random; 49 import java.util.logging.*; 50 import java.util.concurrent.CompletableFuture; 51 import javax.net.ssl.*; 52 import jdk.testlibrary.SimpleSSLContext; 53 54 public class ManyRequests { 55 56 volatile static int counter = 0; 57 58 public static void main(String[] args) throws Exception { 59 Logger logger = Logger.getLogger("com.sun.net.httpserver"); 60 logger.setLevel(Level.ALL); 61 logger.info("TEST"); 62 63 SSLContext ctx = new SimpleSSLContext().get(); 64 65 InetSocketAddress addr = new InetSocketAddress(0); 66 HttpsServer server = HttpsServer.create(addr, 0); 67 server.setHttpsConfigurator(new Configurator(ctx)); 68 69 HttpClient client = HttpClient.create() 70 .sslContext(ctx) 71 .build(); 72 try { 73 test(server, client); 74 System.out.println("OK"); 75 } finally { 76 server.stop(0); 77 client.executorService().shutdownNow(); 78 } 79 } 80 81 //static final int REQUESTS = 1000; 82 static final int REQUESTS = 20; 83 84 static void test(HttpsServer server, HttpClient client) throws Exception { 85 int port = server.getAddress().getPort(); 86 URI uri = new URI("https://127.0.0.1:" + port + "/foo/x"); 87 server.createContext("/foo", new EchoHandler()); 88 server.start(); 89 90 RequestLimiter limiter = new RequestLimiter(40); 91 Random rand = new Random(); 92 CompletableFuture<Void>[] results = new CompletableFuture[REQUESTS]; 93 HashMap<HttpRequest,byte[]> bodies = new HashMap<>(); 94 95 for (int i=0; i<REQUESTS; i++) { 96 byte[] buf = new byte[i+1]; // different size bodies 97 rand.nextBytes(buf); 98 HttpRequest r = client.request(uri) 99 .body(HttpRequest.fromByteArray(buf)) 100 .POST(); 101 bodies.put(r, buf); 102 103 results[i] = 104 limiter.whenOkToSend() 105 .thenCompose((v) -> r.responseAsync()) 106 .thenCompose((resp) -> { 107 limiter.requestComplete(); 108 if (resp.statusCode() != 200) { 109 resp.bodyAsync(HttpResponse.ignoreBody()); 110 String s = "Expected 200, got: " + resp.statusCode(); 111 return completedWithIOException(s); 112 } else { 113 counter++; 114 System.out.println("Result from " + counter); 115 } 116 return resp.bodyAsync(HttpResponse.asByteArray()) 117 .thenApply((b) -> new Pair<>(resp, b)); 118 }) 119 .thenAccept((pair) -> { 120 HttpRequest request = pair.t.request(); 121 byte[] requestBody = bodies.get(request); 122 check(Arrays.equals(requestBody, pair.u), 123 "bodies not equal"); 124 125 }); 126 } 127 128 // wait for them all to complete and throw exception in case of error 129 //try { 130 CompletableFuture.allOf(results).join(); 131 //} catch (Exception e) { 132 //e.printStackTrace(); 133 //throw e; 134 //} 135 } 136 137 static <T> CompletableFuture<T> completedWithIOException(String message) { 138 return CompletableFuture.failedFuture(new IOException(message)); 139 } 140 141 static final class Pair<T,U> { 142 Pair(T t, U u) { 143 this.t = t; this.u = u; 144 } 145 T t; 146 U u; 147 } 148 149 /** 150 * A simple limiter for controlling the number of requests to be run in 151 * parallel whenOkToSend() is called which returns a CF<Void> that allows 152 * each individual request to proceed, or block temporarily (blocking occurs 153 * on the waiters list here. As each request actually completes 154 * requestComplete() is called to notify this object, and allow some 155 * requests to continue. 156 */ 157 static class RequestLimiter { 158 189 blocked = true; 190 CompletableFuture<Void> r = new CompletableFuture<>(); 191 waiters.add(r); 192 return r; 193 } else { 194 number++; 195 return COMPLETED_FUTURE; 196 } 197 } 198 } 199 200 static void check(boolean cond, Object... msg) { 201 if (cond) 202 return; 203 StringBuilder sb = new StringBuilder(); 204 for (Object o : msg) 205 sb.append(o); 206 throw new RuntimeException(sb.toString()); 207 } 208 } 209 210 class Configurator extends HttpsConfigurator { 211 public Configurator(SSLContext ctx) { 212 super(ctx); 213 } 214 215 public void configure (HttpsParameters params) { 216 params.setSSLParameters (getSSLContext().getSupportedSSLParameters()); 217 } 218 } 219 |