Java tutorial
/*---------------------------------------------------------------------- * Copyright 2017 realglobe Inc. * * Licensed 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 jp.realglobe.util.uploader; import java.io.IOException; import java.net.HttpURLConnection; import java.net.InetSocketAddress; import java.nio.file.Files; import java.nio.file.Path; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import org.apache.commons.io.FileUtils; import org.json.JSONObject; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpServer; /** * ??? DirectoryUploader ? */ public class DirectoryUploaderWithServerTest { private static class MemoryStore implements Store { private final Map<String, String> store = new HashMap<>(); @Override public String load(final String key) { return this.store.get(key); } @Override public void clear(final String key) throws Exception { this.store.remove(key); } @Override public void store(final String key, final String value) throws Exception { this.store.put(key, value); } } private static class HttpRequest { private final String path; private final byte[] body; HttpRequest(final HttpExchange exchange) throws IOException { this.path = exchange.getRequestURI().getPath(); this.body = Utils.readAll(exchange.getRequestBody()); } public String getPath() { return this.path; } public byte[] getBody() { return this.body; } } BlockingQueue<HttpRequest> requestQueue; ExecutorService executor; String uploaderId; Path targetDirectory; HttpServer server; /** * ?? * @throws IOException * @throws InterruptedException ???? */ @Before public void setUp() throws IOException, InterruptedException { this.requestQueue = new LinkedBlockingQueue<>(); this.executor = Executors.newCachedThreadPool(); this.uploaderId = String.valueOf(Math.abs(System.nanoTime())); this.targetDirectory = Files.createTempDirectory(""); try { this.server = HttpServer.create(new InetSocketAddress(0), 0); this.server.createContext("/", this::handle); this.server.start(); } catch (final IOException e) { FileUtils.deleteDirectory(this.targetDirectory.toFile()); throw e; } // ?? Thread.sleep(1_000); } private void handle(final HttpExchange exchange) throws IOException { final String path = exchange.getRequestURI().getPath(); if (path.equals(Constants.URL_PATH_TOKEN)) { final Map<String, Object> tokenData = new HashMap<>(); tokenData.put(Constants.TOKEN_RESPONSE_KEY_TOKEN, "abcde"); final Map<String, Object> data = new HashMap<>(); data.put(Constants.TOKEN_RESPONSE_KEY_DATA, tokenData); Utils.readAll(exchange.getRequestBody()); exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, 0); exchange.getResponseBody().write((new JSONObject(data)).toString().getBytes()); } else if (path.startsWith(Constants.URL_PATH_UPLOAD_PREFIX) && path .substring(Constants.URL_PATH_UPLOAD_PREFIX.length()).endsWith(Constants.URL_PATH_UPLOAD_SUFFIX)) { this.requestQueue.offer(new HttpRequest(exchange)); exchange.sendResponseHeaders(HttpURLConnection.HTTP_CREATED, 0); } exchange.close(); } /** * ???? * @throws IOException * @throws InterruptedException ???? */ @After public void tearDown() throws IOException, InterruptedException { this.executor.shutdownNow(); try { this.executor.awaitTermination(1, TimeUnit.SECONDS); } finally { this.server.stop(0); FileUtils.deleteDirectory(this.targetDirectory.toFile()); } } private String getBaseUrl() { return "http://localhost:" + this.server.getAddress().getPort(); } /** * * @throws Exception */ @Test public void testUpload() throws Exception { final long delay = 1_000L; final DirectoryUploader uploader = new DirectoryUploader(this.targetDirectory, delay, false, null, 0, 0, getBaseUrl(), "user0", "test uploader", new MemoryStore()); uploader.prepareToken(); final Future<?> future = this.executor.submit(uploader); // ? Thread.sleep(1_000L); Files.write(this.targetDirectory.resolve("test"), new byte[] { (byte) 0 }); final HttpRequest request = this.requestQueue.poll(1_000L + delay, TimeUnit.MILLISECONDS); try { future.get(0, TimeUnit.MILLISECONDS); } catch (final TimeoutException e) { // ????? } Assert.assertEquals( Constants.URL_PATH_UPLOAD_PREFIX + "/" + uploader.getId() + Constants.URL_PATH_UPLOAD_SUFFIX, request.getPath()); } /** * ?? * @throws Exception */ @Test public void testExtensionRestriction() throws Exception { final long delay = 1_000L; final DirectoryUploader uploader = new DirectoryUploader(this.targetDirectory, delay, false, Arrays.asList("jpg"), 0, 0, getBaseUrl(), "user0", "test uploader", new MemoryStore()); uploader.prepareToken(); final Future<?> future = this.executor.submit(uploader); // ? Thread.sleep(1_000L); Files.write(this.targetDirectory.resolve("test.png"), new byte[] { (byte) 0 }); Files.write(this.targetDirectory.resolve("test.jpg"), new byte[] { (byte) 0 }); final HttpRequest request = this.requestQueue.poll(1_000L + delay, TimeUnit.MILLISECONDS); Assert.assertNull(this.requestQueue.poll()); try { future.get(0, TimeUnit.MILLISECONDS); } catch (final TimeoutException e) { // ????? } Assert.assertEquals( Constants.URL_PATH_UPLOAD_PREFIX + "/" + uploader.getId() + Constants.URL_PATH_UPLOAD_SUFFIX, request.getPath()); } /** * ?? * @throws Exception */ @Test public void testMinimumLimitation() throws Exception { final long delay = 1_000L; final DirectoryUploader uploader = new DirectoryUploader(this.targetDirectory, delay, false, null, 2, 0, getBaseUrl(), "user0", "test uploader", new MemoryStore()); uploader.prepareToken(); final Future<?> future = this.executor.submit(uploader); // ? Thread.sleep(1_000L); Files.write(this.targetDirectory.resolve("test0"), new byte[] { (byte) 0 }); Files.write(this.targetDirectory.resolve("test1"), new byte[] { (byte) 0, (byte) 1 }); final HttpRequest request = this.requestQueue.poll(1_000L + delay, TimeUnit.MILLISECONDS); Assert.assertNull(this.requestQueue.poll()); Assert.assertNull(this.requestQueue.poll()); try { future.get(0, TimeUnit.MILLISECONDS); } catch (final TimeoutException e) { // ????? } Assert.assertEquals( Constants.URL_PATH_UPLOAD_PREFIX + "/" + uploader.getId() + Constants.URL_PATH_UPLOAD_SUFFIX, request.getPath()); } /** * ? * @throws Exception */ @Test public void testMaximumLimitation() throws Exception { final long delay = 1_000L; final DirectoryUploader uploader = new DirectoryUploader(this.targetDirectory, delay, false, null, 0, 1, getBaseUrl(), "user0", "test uploader", new MemoryStore()); uploader.prepareToken(); final Future<?> future = this.executor.submit(uploader); // ? Thread.sleep(1_000L); Files.write(this.targetDirectory.resolve("test0"), new byte[] { (byte) 0 }); Files.write(this.targetDirectory.resolve("test1"), new byte[] { (byte) 0, (byte) 1 }); final HttpRequest request = this.requestQueue.poll(1_000L + delay, TimeUnit.MILLISECONDS); Assert.assertNull(this.requestQueue.poll()); try { future.get(0, TimeUnit.MILLISECONDS); } catch (final TimeoutException e) { // ????? } Assert.assertEquals( Constants.URL_PATH_UPLOAD_PREFIX + "/" + uploader.getId() + Constants.URL_PATH_UPLOAD_SUFFIX, request.getPath()); } }