This is an automated email from the ASF dual-hosted git repository. spmallette pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/tinkerpop.git
commit d8f192d128b23cb547750087b149f5424b2cd1e2 Merge: eac6b93ffe dd4392a310 Author: Stephen Mallette <stepm...@amazon.com> AuthorDate: Tue Jul 11 06:17:10 2023 -0400 Merge branch '3.6-dev' CHANGELOG.asciidoc | 1 + docs/src/reference/gremlin-applications.asciidoc | 2 +- .../gremlin/server/GremlinServerHttpIntegrateTest.java | 13 +++++++++++++ .../gremlin/util/ser/GraphSONMessageSerializerV1d0.java | 4 ++-- .../gremlin/util/ser/GraphSONMessageSerializerV2d0.java | 16 ++++++++-------- .../org/apache/tinkerpop/gremlin/util/ser/SerTokens.java | 1 + .../apache/tinkerpop/gremlin/util/ser/Serializers.java | 3 +++ 7 files changed, 29 insertions(+), 11 deletions(-) diff --cc gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java index c1291bf498,0000000000..be3e2809d4 mode 100644,000000..100644 --- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java +++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV1d0.java @@@ -1,127 -1,0 +1,127 @@@ +/* + * 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.util.ser; + +import io.netty.buffer.ByteBufAllocator; +import org.apache.tinkerpop.gremlin.util.message.RequestMessage; +import org.apache.tinkerpop.gremlin.util.message.ResponseMessage; +import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion; +import org.apache.tinkerpop.gremlin.structure.io.graphson.TypeInfo; +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; +import java.util.Map; +import java.util.UUID; + +/** + * Serialize results to JSON with version 1.0.x schema. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public final class GraphSONMessageSerializerV1d0 extends AbstractGraphSONMessageSerializerV1d0 implements MessageTextSerializer<ObjectMapper> { + private static final Logger logger = LoggerFactory.getLogger(GraphSONMessageSerializerV1d0.class); - private static final String MIME_TYPE = SerTokens.MIME_JSON; ++ private static final String MIME_TYPE = SerTokens.MIME_GRAPHSON_V1D0_SPARSE; + + private static byte[] header; + + static { + final ByteBuffer buffer = ByteBuffer.allocate(MIME_TYPE.length() + 1); + buffer.put((byte) MIME_TYPE.length()); + buffer.put(MIME_TYPE.getBytes()); + header = buffer.array(); + } + + public GraphSONMessageSerializerV1d0() { + super(); + } + + public GraphSONMessageSerializerV1d0(final GraphSONMapper mapper) { + super(mapper); + } + + @Override + public String[] mimeTypesSupported() { - return new String[]{MIME_TYPE}; ++ return new String[]{MIME_TYPE, SerTokens.MIME_JSON}; + } + + @Override + GraphSONMapper.Builder configureBuilder(final GraphSONMapper.Builder builder) { + // already set to 1.0 in AbstractGraphSONMessageSerializerV1d0 + return builder.addCustomModule(new GremlinServerModule()) + .typeInfo(TypeInfo.NO_TYPES); + } + + @Override + byte[] obtainHeader() { + return header; + } + + @Override + public ResponseMessage deserializeResponse(final String msg) throws SerializationException { + try { + final Map<String, Object> responseData = mapper.readValue(msg, mapTypeReference); + final Map<String, Object> status = (Map<String, Object>) responseData.get(SerTokens.TOKEN_STATUS); + final Map<String, Object> result = (Map<String, Object>) responseData.get(SerTokens.TOKEN_RESULT); + return ResponseMessage.build(UUID.fromString(responseData.get(SerTokens.TOKEN_REQUEST).toString())) + .code(ResponseStatusCode.getFromValue((Integer) status.get(SerTokens.TOKEN_CODE))) + .statusMessage(String.valueOf(status.get(SerTokens.TOKEN_MESSAGE))) + .statusAttributes((Map<String, Object>) status.get(SerTokens.TOKEN_ATTRIBUTES)) + .result(result.get(SerTokens.TOKEN_DATA)) + .responseMetaData((Map<String, Object>) result.get(SerTokens.TOKEN_META)) + .create(); + } catch (Exception ex) { + logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV1d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { + try { + return mapper.writeValueAsString(responseMessage); + } catch (Exception ex) { + logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV1d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public RequestMessage deserializeRequest(final String msg) throws SerializationException { + try { + return mapper.readValue(msg, RequestMessage.class); + } catch (Exception ex) { + logger.warn("Request [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV1d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException { + try { + return mapper.writeValueAsString(requestMessage); + } catch (Exception ex) { + logger.warn("Request [{}] could not be serialized by {}.", requestMessage.toString(), AbstractGraphSONMessageSerializerV1d0.class.getName()); + throw new SerializationException(ex); + } + } +} diff --cc gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java index d0a434a90b,0000000000..24dbafc460 mode 100644,000000..100644 --- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java +++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/GraphSONMessageSerializerV2d0.java @@@ -1,140 -1,0 +1,140 @@@ +/* + * 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.util.ser; + +import io.netty.buffer.ByteBufAllocator; +import org.apache.tinkerpop.gremlin.util.message.RequestMessage; +import org.apache.tinkerpop.gremlin.util.message.ResponseMessage; +import org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONVersion; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONXModuleV2d0; +import org.apache.tinkerpop.gremlin.structure.io.graphson.TypeInfo; +import org.apache.tinkerpop.shaded.jackson.databind.ObjectMapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.nio.ByteBuffer; + +/** + * Serialize results to JSON with version 2.0.x schema and the extended module. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public final class GraphSONMessageSerializerV2d0 extends AbstractGraphSONMessageSerializerV2d0 implements MessageTextSerializer<ObjectMapper> { + private static final Logger logger = LoggerFactory.getLogger(GraphSONMessageSerializerV2d0.class); + private static final String MIME_TYPE = SerTokens.MIME_GRAPHSON_V2D0; + + private static byte[] header; + + static { + final ByteBuffer buffer = ByteBuffer.allocate(MIME_TYPE.length() + 1); + buffer.put((byte) MIME_TYPE.length()); + buffer.put(MIME_TYPE.getBytes()); + header = buffer.array(); + } + - /** - * Creates a default GraphSONMessageSerializer. - * - * By default this will internally instantiate a {@link GraphSONMapper} and register - * a {@link GremlinServerModule} and {@link GraphSONXModuleV2d0} to the mapper. - * - * @see #GraphSONMessageSerializerV2d0(GraphSONMapper.Builder) - */ ++ /** ++ * Creates a default GraphSONMessageSerializer. ++ * ++ * By default this will internally instantiate a {@link GraphSONMapper} and register ++ * a {@link GremlinServerModule} and {@link GraphSONXModuleV2d0} to the mapper. ++ * ++ * @see #GraphSONMessageSerializerV2d0(GraphSONMapper.Builder) ++ */ + public GraphSONMessageSerializerV2d0() { + super(); + } + + /** + * Create a GraphSONMessageSerializer from a {@link GraphSONMapper}. Deprecated, use + * {@link #GraphSONMessageSerializerV2d0(GraphSONMapper.Builder)} instead. + */ + @Deprecated + public GraphSONMessageSerializerV2d0(final GraphSONMapper mapper) { + super(mapper); + } + + /** + * Create a GraphSONMessageSerializer with a provided {@link GraphSONMapper.Builder}. + * + * Note that to make this mapper usable in the context of request messages and responses, + * this method will automatically register a {@link GremlinServerModule} to the provided + * mapper. + */ + public GraphSONMessageSerializerV2d0(final GraphSONMapper.Builder mapperBuilder) { + super(mapperBuilder); + } + + @Override + public String[] mimeTypesSupported() { + return new String[]{MIME_TYPE, SerTokens.MIME_JSON}; + } + + @Override + GraphSONMapper.Builder configureBuilder(final GraphSONMapper.Builder builder) { + // already set to 2.0 in AbstractGraphSONMessageSerializerV2d0 + return builder.typeInfo(TypeInfo.PARTIAL_TYPES).addCustomModule(new GremlinServerModule()); + } + + @Override + byte[] obtainHeader() { + return header; + } + + @Override + public ResponseMessage deserializeResponse(final String msg) throws SerializationException { + try { + return mapper.readValue(msg, ResponseMessage.class); + } catch (Exception ex) { + logger.warn("Response [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public String serializeResponseAsString(final ResponseMessage responseMessage, final ByteBufAllocator allocator) throws SerializationException { + try { + return mapper.writeValueAsString(responseMessage); + } catch (Exception ex) { + logger.warn("Response [{}] could not be serialized by {}.", responseMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public RequestMessage deserializeRequest(final String msg) throws SerializationException { + try { + return mapper.readValue(msg, RequestMessage.class); + } catch (Exception ex) { + logger.warn("Request [{}] could not be deserialized by {}.", msg, AbstractGraphSONMessageSerializerV2d0.class.getName()); + throw new SerializationException(ex); + } + } + + @Override + public String serializeRequestAsString(final RequestMessage requestMessage, final ByteBufAllocator allocator) throws SerializationException { + try { + return mapper.writeValueAsString(requestMessage); + } catch (Exception ex) { + logger.warn("Request [{}] could not be serialized by {}.", requestMessage.toString(), AbstractGraphSONMessageSerializerV2d0.class.getName()); + throw new SerializationException(ex); + } + } +} diff --cc gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/SerTokens.java index bbc1a5ea22,0000000000..3ce6dbcab8 mode 100644,000000..100644 --- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/SerTokens.java +++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/SerTokens.java @@@ -1,46 -1,0 +1,47 @@@ +/* + * 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.util.ser; + +import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy; + +/** + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public final class SerTokens { + private SerTokens() {} + + public static final String TOKEN_ATTRIBUTES = "attributes"; + public static final String TOKEN_RESULT = "result"; + public static final String TOKEN_STATUS = "status"; + public static final String TOKEN_DATA = "data"; + public static final String TOKEN_META = "meta"; + public static final String TOKEN_CODE = "code"; + public static final String TOKEN_REQUEST = "requestId"; + public static final String TOKEN_MESSAGE = "message"; + public static final String TOKEN_PROCESSOR = "processor"; + public static final String TOKEN_OP = "op"; + public static final String TOKEN_ARGS = "args"; + + public static final String MIME_JSON = "application/json"; + public static final String MIME_GRAPHSON_V1D0 = "application/vnd.gremlin-v1.0+json"; ++ public static final String MIME_GRAPHSON_V1D0_SPARSE = "application/vnd.gremlin-v1.0+json;sparse=true"; + public static final String MIME_GRAPHSON_V2D0 = "application/vnd.gremlin-v2.0+json"; + public static final String MIME_GRAPHSON_V3D0 = "application/vnd.gremlin-v3.0+json"; + public static final String MIME_GRAPHBINARY_V1D0 = "application/vnd.graphbinary-v1.0"; +} diff --cc gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/Serializers.java index aea03691c9,0000000000..f14f55b5a5 mode 100644,000000..100644 --- a/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/Serializers.java +++ b/gremlin-util/src/main/java/org/apache/tinkerpop/gremlin/util/ser/Serializers.java @@@ -1,65 -1,0 +1,68 @@@ +/* + * 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.util.ser; + +import org.apache.tinkerpop.gremlin.util.MessageSerializer; +import org.apache.tinkerpop.gremlin.process.traversal.strategy.decoration.HaltedTraverserStrategy; + +/** + * An enum of the default serializers. + * + * @author Stephen Mallette (http://stephen.genoprime.com) + */ +public enum Serializers { + + /** + * GraphSON 3.0. + */ + GRAPHSON(SerTokens.MIME_JSON), + GRAPHSON_V1D0(SerTokens.MIME_GRAPHSON_V1D0), ++ GRAPHSON_V1D0_SPARSE(SerTokens.MIME_GRAPHSON_V1D0_SPARSE), + GRAPHSON_V2D0(SerTokens.MIME_GRAPHSON_V2D0), + GRAPHSON_V3D0(SerTokens.MIME_GRAPHSON_V3D0), + GRAPHBINARY_V1D0(SerTokens.MIME_GRAPHBINARY_V1D0); + + private String value; + + Serializers(final String mimeType) { + this.value = mimeType; + } + + public String getValue() { + return value; + } + + public MessageSerializer<?> simpleInstance() { + switch (value) { + case SerTokens.MIME_JSON: + case SerTokens.MIME_GRAPHSON_V3D0: + return new GraphSONMessageSerializerV3d0(); + case SerTokens.MIME_GRAPHSON_V1D0: + return new GraphSONMessageSerializerGremlinV1d0(); ++ case SerTokens.MIME_GRAPHSON_V1D0_SPARSE: ++ return new GraphSONMessageSerializerV1d0(); + case SerTokens.MIME_GRAPHSON_V2D0: + return new GraphSONMessageSerializerV2d0(); + case SerTokens.MIME_GRAPHBINARY_V1D0: + return new GraphBinaryMessageSerializerV1(); + default: + throw new RuntimeException("Could not create a simple MessageSerializer instance of " + value); + } + } +}