/*
* Copyright 2010 Proofpoint, 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 io.airlift.sample;
import com.google.common.base.Charsets;
import com.google.common.collect.ImmutableList;
import com.google.common.io.Resources;
import com.google.inject.Injector;
import io.airlift.bootstrap.Bootstrap;
import io.airlift.bootstrap.LifeCycleManager;
import io.airlift.event.client.InMemoryEventClient;
import io.airlift.event.client.InMemoryEventModule;
import io.airlift.http.client.HttpClient;
import io.airlift.http.client.StatusResponseHandler.StatusResponse;
import io.airlift.http.client.jetty.JettyHttpClient;
import io.airlift.http.server.testing.TestingHttpServer;
import io.airlift.http.server.testing.TestingHttpServerModule;
import io.airlift.jaxrs.JaxrsModule;
import io.airlift.json.JsonCodec;
import io.airlift.json.JsonModule;
import io.airlift.node.testing.TestingNodeModule;
import io.airlift.testing.Closeables;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static io.airlift.http.client.JsonResponseHandler.createJsonResponseHandler;
import static io.airlift.http.client.Request.Builder.prepareDelete;
import static io.airlift.http.client.Request.Builder.prepareGet;
import static io.airlift.http.client.Request.Builder.preparePost;
import static io.airlift.http.client.Request.Builder.preparePut;
import static io.airlift.http.client.StaticBodyGenerator.createStaticBodyGenerator;
import static io.airlift.http.client.StatusResponseHandler.createStatusResponseHandler;
import static io.airlift.json.JsonCodec.listJsonCodec;
import static io.airlift.json.JsonCodec.mapJsonCodec;
import static io.airlift.sample.PersonEvent.personAdded;
import static io.airlift.sample.PersonEvent.personRemoved;
import static io.airlift.testing.Assertions.assertEqualsIgnoreOrder;
import static javax.ws.rs.core.HttpHeaders.CONTENT_TYPE;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
public class TestServer
{
private static final int NOT_ALLOWED = 405;
private HttpClient client;
private TestingHttpServer server;
private PersonStore store;
private final JsonCodec<Map<String, Object>> mapCodec = mapJsonCodec(String.class, Object.class);
private final JsonCodec<List<Object>> listCodec = listJsonCodec(Object.class);
private InMemoryEventClient eventClient;
private LifeCycleManager lifeCycleManager;
@BeforeMethod
public void setup()
throws Exception
{
Bootstrap app = new Bootstrap(
new TestingNodeModule(),
new InMemoryEventModule(),
new TestingHttpServerModule(),
new JsonModule(),
new JaxrsModule(true),
new MainModule());
Injector injector = app
.strictConfig()
.doNotInitializeLogging()
.initialize();
lifeCycleManager = injector.getInstance(LifeCycleManager.class);
server = injector.getInstance(TestingHttpServer.class);
store = injector.getInstance(PersonStore.class);
eventClient = injector.getInstance(InMemoryEventClient.class);
client = new JettyHttpClient();
}
@AfterMethod
public void teardown()
throws Exception
{
try {
if (lifeCycleManager != null) {
lifeCycleManager.stop();
}
}
finally {
Closeables.closeQuietly(client);
}
}
@Test
public void testEmpty()
throws Exception
{
List<Object> response = client.execute(
prepareGet().setUri(uriFor("/v1/person")).build(),
createJsonResponseHandler(listCodec));
assertEquals(response, Collections.<Object>emptyList());
}
@Test
public void testGetAll()
throws IOException, ExecutionException, InterruptedException
{
store.put("bar", new Person("bar@example.com", "Mr Bar"));
store.put("foo", new Person("foo@example.com", "Mr Foo"));
List<Object> expected = listCodec.fromJson(Resources.toString(Resources.getResource("list.json"), Charsets.UTF_8));
List<Object> actual = client.execute(
prepareGet().setUri(uriFor("/v1/person")).build(),
createJsonResponseHandler(listCodec));
assertEqualsIgnoreOrder(expected, actual);
}
@Test
public void testGetSingle()
throws IOException, ExecutionException, InterruptedException
{
store.put("foo", new Person("foo@example.com", "Mr Foo"));
URI requestUri = uriFor("/v1/person/foo");
Map<String, Object> expected = mapCodec.fromJson(Resources.toString(Resources.getResource("single.json"), Charsets.UTF_8));
expected.put("self", requestUri.toString());
Map<String, Object> actual = client.execute(
prepareGet().setUri(requestUri).build(),
createJsonResponseHandler(mapCodec));
assertEquals(actual, expected);
}
@Test
public void testPut()
throws IOException, ExecutionException, InterruptedException
{
String json = Resources.toString(Resources.getResource("single.json"), Charsets.UTF_8);
StatusResponse response = client.execute(
preparePut()
.setUri(uriFor("/v1/person/foo"))
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.setBodyGenerator(createStaticBodyGenerator(json, Charsets.UTF_8))
.build(),
createStatusResponseHandler());
assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.CREATED.getStatusCode());
assertEquals(store.get("foo"), new Person("foo@example.com", "Mr Foo"));
assertEquals(eventClient.getEvents(), ImmutableList.of(
personAdded("foo", new Person("foo@example.com", "Mr Foo"))
));
}
@Test
public void testDelete()
throws IOException, ExecutionException, InterruptedException
{
store.put("foo", new Person("foo@example.com", "Mr Foo"));
StatusResponse response = client.execute(
prepareDelete()
.setUri(uriFor("/v1/person/foo"))
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.build(),
createStatusResponseHandler());
assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NO_CONTENT.getStatusCode());
assertNull(store.get("foo"));
assertEquals(eventClient.getEvents(), ImmutableList.of(
personAdded("foo", new Person("foo@example.com", "Mr Foo")),
personRemoved("foo", new Person("foo@example.com", "Mr Foo"))
));
}
@Test
public void testDeleteMissing()
throws IOException, ExecutionException, InterruptedException
{
StatusResponse response = client.execute(
prepareDelete()
.setUri(uriFor("/v1/person/foo"))
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.build(),
createStatusResponseHandler());
assertEquals(response.getStatusCode(), javax.ws.rs.core.Response.Status.NOT_FOUND.getStatusCode());
}
@Test
public void testPostNotAllowed()
throws IOException, ExecutionException, InterruptedException
{
String json = Resources.toString(Resources.getResource("single.json"), Charsets.UTF_8);
StatusResponse response = client.execute(
preparePost()
.setUri(uriFor("/v1/person/foo"))
.addHeader(CONTENT_TYPE, APPLICATION_JSON)
.setBodyGenerator(createStaticBodyGenerator(json, Charsets.UTF_8))
.build(),
createStatusResponseHandler());
assertEquals(response.getStatusCode(), NOT_ALLOWED);
assertNull(store.get("foo"));
}
private URI uriFor(String path)
{
return server.getBaseUrl().resolve(path);
}
}