blob: 6b911d9b2ed4bfa2ab17b8408ee9e192de4dd21d [file] [log] [blame]
/*
* 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.
*/
package org.apache.tinkerpop.gremlin.server.handler;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringEncoder;
import io.netty.util.CharsetUtil;
import org.apache.tinkerpop.gremlin.driver.MessageSerializer;
import org.apache.tinkerpop.gremlin.driver.Tokens;
import org.apache.tinkerpop.gremlin.driver.message.RequestMessage;
import org.apache.tinkerpop.gremlin.driver.ser.GraphBinaryMessageSerializerV1;
import org.apache.tinkerpop.gremlin.driver.ser.GraphSONMessageSerializerV3d0;
import org.apache.tinkerpop.gremlin.driver.ser.SerTokens;
import org.apache.tinkerpop.gremlin.driver.ser.SerializationException;
import org.junit.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.samePropertyValuesAs;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
public class HttpHandlerUtilTest {
private final ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
private final GraphBinaryMessageSerializerV1 graphBinarySerializer = new GraphBinaryMessageSerializerV1();
public final GraphSONMessageSerializerV3d0 graphSONSerializer = new GraphSONMessageSerializerV3d0();
@Test
public void shouldFailWhenIncorrectSerializerUsed() throws SerializationException {
final RequestMessage request = RequestMessage.build(Tokens.OPS_BYTECODE)
.processor("traversal")
.overrideRequestId(UUID.randomUUID())
.addArg(Tokens.ARGS_GREMLIN, "g.V()")
.create();
final ByteBuf buffer = graphSONSerializer.serializeRequestAsBinary(request, allocator);
final HttpHeaders headers = new DefaultHttpHeaders();
headers.add(HttpHeaderNames.CONTENT_TYPE, SerTokens.MIME_GRAPHBINARY_V1D0);
final FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "some uri",
buffer, headers, new DefaultHttpHeaders());
final Map<String, MessageSerializer<?>> serializers = new HashMap<>();
serializers.put(SerTokens.MIME_GRAPHBINARY_V1D0, graphBinarySerializer);
try {
HttpHandlerUtil.getRequestMessageFromHttpRequest(httpRequest, serializers);
fail("SerializationException expected");
} catch (IllegalArgumentException ex) {
assertEquals("Mime type mismatch. Value in content-type header is not equal payload header.", ex.getMessage());
}
}
@Test
public void shouldCorrectlyDeserializeRequestMessage() throws SerializationException {
final RequestMessage request = RequestMessage.build(Tokens.OPS_BYTECODE)
.processor("traversal")
.overrideRequestId(UUID.randomUUID())
.addArg(Tokens.ARGS_GREMLIN, "g.V()")
.create();
final ByteBuf buffer = graphBinarySerializer.serializeRequestAsBinary(request, allocator);
final HttpHeaders headers = new DefaultHttpHeaders();
headers.add(HttpHeaderNames.CONTENT_TYPE, SerTokens.MIME_GRAPHBINARY_V1D0);
final FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "some uri",
buffer, headers, new DefaultHttpHeaders());
final Map<String, MessageSerializer<?>> serializers = new HashMap<>();
serializers.put(SerTokens.MIME_GRAPHBINARY_V1D0, graphBinarySerializer);
final RequestMessage deserialized = HttpHandlerUtil.getRequestMessageFromHttpRequest(httpRequest, serializers);
assertThat(request, samePropertyValuesAs(deserialized));
}
@Test
public void shouldCorrectlyDeserializeGremlinFromPostRequest() throws SerializationException {
final String gremlin = "g.V().hasLabel('person')";
final UUID requestId = UUID.randomUUID();
final ByteBuf buffer = allocator.buffer();
buffer.writeCharSequence("{ \"gremlin\": \"" + gremlin +
"\", \"requestId\": \"" + requestId +
"\", \"language\": \"gremlin-groovy\"}",
CharsetUtil.UTF_8);
final HttpHeaders headers = new DefaultHttpHeaders();
headers.add(HttpHeaderNames.CONTENT_TYPE, SerTokens.MIME_JSON);
final FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.POST, "some uri",
buffer, headers, new DefaultHttpHeaders());
final Map<String, MessageSerializer<?>> serializers = new HashMap<>();
serializers.put(SerTokens.MIME_GRAPHBINARY_V1D0, graphBinarySerializer);
final RequestMessage deserialized = HttpHandlerUtil.getRequestMessageFromHttpRequest(httpRequest, serializers);
assertEquals(gremlin, deserialized.getArgs().get(Tokens.ARGS_GREMLIN));
assertEquals(requestId, deserialized.getRequestId());
assertEquals("gremlin-groovy", deserialized.getArg(Tokens.ARGS_LANGUAGE));
}
@Test
public void shouldCorrectlyDeserializeGremlinFromGetRequest() throws SerializationException {
final String gremlin = "g.V().hasLabel('person')";
final UUID requestId = UUID.randomUUID();
final ByteBuf buffer = allocator.buffer();
final List<String> headerOptions = Arrays.asList("", null, SerTokens.MIME_JSON, "some invalid value");
for (final String contentTypeValue : headerOptions) {
final HttpHeaders headers = new DefaultHttpHeaders();
if (contentTypeValue != null) {
headers.add(HttpHeaderNames.CONTENT_TYPE, contentTypeValue);
}
final QueryStringEncoder encoder = new QueryStringEncoder("/");
encoder.addParam("gremlin", gremlin);
encoder.addParam("requestId", requestId.toString());
encoder.addParam("language", "gremlin-groovy");
final FullHttpRequest httpRequest = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
encoder.toString(), buffer, headers, new DefaultHttpHeaders());
final Map<String, MessageSerializer<?>> serializers = new HashMap<>();
serializers.put(SerTokens.MIME_GRAPHBINARY_V1D0, graphBinarySerializer);
final RequestMessage deserialized = HttpHandlerUtil.getRequestMessageFromHttpRequest(httpRequest, serializers);
assertEquals(gremlin, deserialized.getArgs().get(Tokens.ARGS_GREMLIN));
assertEquals(requestId, deserialized.getRequestId());
assertEquals("gremlin-groovy", deserialized.getArg(Tokens.ARGS_LANGUAGE));
}
}
}