Skip to content

Commit

Permalink
GEODE-4080: Protobuf JSON objects are in a proto string (apache#1171)
Browse files Browse the repository at this point in the history
* GEODE-4080: Protobuf JSON objects are in a proto string

In the process, remove a couple of serialization-related classes that
are no longer really applicable.

* Catch `JSONFormatterException` and return it as a `EncodingException`.
* Change some names and add ProtobufSerializationService, which is the big
reason for all this churn.
* Get rid of the codec package
* Inline the serialization type enum
* Make encoding methods throw EncodingException.
* Don't use exceptions for control flow.

This meant renaming ProtobufPrimitiveTypes to ProtobufEncodingTypes.

Signed-off-by: Brian Rowe <[email protected]>
  • Loading branch information
galen-pivotal authored Dec 20, 2017
1 parent 635ab6a commit e24e038
Show file tree
Hide file tree
Showing 49 changed files with 432 additions and 844 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,21 @@

import java.util.function.Function;

import org.apache.geode.SerializationException;
import org.apache.geode.annotations.Experimental;
import org.apache.geode.internal.protocol.operations.OperationHandler;
import org.apache.geode.security.ResourcePermission;

@Experimental
public abstract class OperationContext<OperationRequest, OperationResponse, ErrorResponse, ProtocolRequest, ProtocolResponse> {
private final OperationHandler<OperationRequest, OperationResponse, ErrorResponse> operationHandler;
public abstract class OperationContext<OperationRequest, OperationResponse, ErrorResponse, ProtocolRequest, ProtocolResponse, Serializer> {
private final OperationHandler<OperationRequest, OperationResponse, ErrorResponse, Serializer> operationHandler;
private final Function<ProtocolRequest, OperationRequest> fromRequest;
private final Function<OperationResponse, ProtocolResponse> toResponse;
private final Function<ErrorResponse, ProtocolResponse> toErrorResponse;
private final ResourcePermission accessPermissionRequired;

public OperationContext(Function<ProtocolRequest, OperationRequest> fromRequest,
OperationHandler<OperationRequest, OperationResponse, ErrorResponse> operationHandler,
OperationHandler<OperationRequest, OperationResponse, ErrorResponse, Serializer> operationHandler,
Function<OperationResponse, ProtocolResponse> toResponse,
ResourcePermission permissionRequired) {
this.operationHandler = operationHandler;
Expand All @@ -42,7 +43,7 @@ public OperationContext(Function<ProtocolRequest, OperationRequest> fromRequest,

protected abstract ProtocolResponse makeErrorBuilder(ErrorResponse errorResponse);

public OperationHandler<OperationRequest, OperationResponse, ErrorResponse> getOperationHandler() {
public OperationHandler<OperationRequest, OperationResponse, ErrorResponse, Serializer> getOperationHandler() {
return operationHandler;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.protocol.protobuf.v1.serializer;
package org.apache.geode.internal.protocol;

import java.io.IOException;
import java.io.InputStream;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,25 @@
import org.apache.geode.internal.exception.InvalidExecutionContextException;
import org.apache.geode.internal.protocol.MessageExecutionContext;
import org.apache.geode.internal.protocol.Result;
import org.apache.geode.internal.protocol.serialization.SerializationService;
import org.apache.geode.internal.protocol.state.exception.ConnectionStateException;

/**
* This interface is implemented by a object capable of handling request types 'Req' and returning
* an a response of type 'Resp'
* This interface is implemented by a object capable of handling request types 'Req' and returning a
* response of type 'Resp'.
*
* The Serializer deserializes and serializes values in 'Req' and 'Resp'.
*
*/
@Experimental
public interface OperationHandler<Req, Resp, ErrorResp> {
public interface OperationHandler<Req, Resp, ErrorResp, Serializer> {
/**
* Decode the message, deserialize contained values using the serialization service, do the work
* indicated on the provided cache, and return a response.
*
* @throws ConnectionStateException if the connection is in an invalid state for the operation in
* question.
*/
Result<Resp, ErrorResp> process(SerializationService serializationService, Req request,
Result<Resp, ErrorResp> process(Serializer serializationService, Req request,
MessageExecutionContext messageExecutionContext)
throws InvalidExecutionContextException, ConnectionStateException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,34 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.geode.internal.protocol.serialization.codec;
package org.apache.geode.internal.protocol.serialization;

import org.apache.geode.annotations.Experimental;
import org.apache.geode.internal.protocol.serialization.SerializationType;
import org.apache.geode.internal.protocol.serialization.TypeCodec;
import org.apache.geode.internal.protocol.serialization.TypeConverter;
import org.apache.geode.internal.protocol.serialization.exception.EncodingException;
import org.apache.geode.pdx.JSONFormatter;
import org.apache.geode.pdx.JSONFormatterException;
import org.apache.geode.pdx.PdxInstance;

@Experimental
public class JSONCodec implements TypeCodec<PdxInstance> {
public class JsonPdxConverter implements TypeConverter<String, PdxInstance> {
@Override
public PdxInstance decode(byte[] incoming) {
return JSONFormatter.fromJSON(incoming);
public PdxInstance decode(String incoming) throws EncodingException {
try {
return JSONFormatter.fromJSON(incoming);
} catch (JSONFormatterException ex) {
throw new EncodingException("Could not decode JSON-encoded object ", ex);
}
}

@Override
public byte[] encode(PdxInstance incoming) {
return JSONFormatter.toJSONByteArray(incoming);
public String encode(PdxInstance incoming) throws EncodingException {
try {
return JSONFormatter.toJSON(incoming);
} catch (JSONFormatterException ex) {
throw new EncodingException("Could not encode PDX object as JSON", ex);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
package org.apache.geode.internal.protocol.serialization;

import org.apache.geode.annotations.Experimental;
import org.apache.geode.internal.protocol.serialization.exception.UnsupportedEncodingTypeException;
import org.apache.geode.internal.protocol.serialization.registry.exception.CodecNotRegisteredForTypeException;
import org.apache.geode.internal.protocol.serialization.exception.EncodingException;

/**
* This interface takes an protocol specific encodingTypeValue enum and converts between objects and
Expand All @@ -26,9 +25,7 @@
*/
@Experimental
public interface SerializationService<T> {
Object decode(T encodingTypeValue, byte[] value)
throws UnsupportedEncodingTypeException, CodecNotRegisteredForTypeException;
Object decode(T encodedValue) throws EncodingException;

byte[] encode(T encodingTypeValue, Object value)
throws UnsupportedEncodingTypeException, CodecNotRegisteredForTypeException;
T encode(Object value) throws EncodingException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package org.apache.geode.internal.protocol.serialization;

import org.apache.geode.annotations.Experimental;
import org.apache.geode.internal.protocol.serialization.exception.EncodingException;

/**
* This interface converts a particular type to and from its binary representation.
Expand All @@ -24,10 +25,10 @@
* @param <T> the type this codec knows how to convert
*/
@Experimental
public interface TypeCodec<T> {
T decode(byte[] incoming);
public interface TypeConverter<F, T> {
T decode(F incoming) throws EncodingException;

byte[] encode(T incoming);
F encode(T incoming) throws EncodingException;

/**
* @return the SerializationType corresponding to T
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
* This indicates an encoding type that we don't know how to handle.
*/
@Experimental
public class UnsupportedEncodingTypeException extends Exception {
public UnsupportedEncodingTypeException(String message) {
public class EncodingException extends Exception {
public EncodingException(String message) {
super(message);
}

public UnsupportedEncodingTypeException(String message, Throwable cause) {
public EncodingException(String message, Throwable cause) {
super(message, cause);
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;

import java.io.UnsupportedEncodingException;

import com.google.protobuf.ByteString;
import org.junit.Test;
import org.junit.experimental.categories.Category;

Expand All @@ -40,11 +37,11 @@ public void encodeAndDecode() throws Exception {
}

@Test(expected = IllegalStateException.class)
public void cantDecodeJson() throws UnsupportedEncodingException {
public void cantDecodeJson() throws Exception {
BasicTypes.EncodedValue.Builder builder = BasicTypes.EncodedValue.newBuilder();
BasicTypes.CustomEncodedValue.Builder customEncodedValue =
BasicTypes.CustomEncodedValue.newBuilder().setValue(ByteString.copyFrom("hello", "UTF-8"));
builder.setCustomEncodedValue(customEncodedValue);

builder.setJsonObjectResult("hello").build();

ValueEncoder.decodeValue(builder.build());
}
}
13 changes: 2 additions & 11 deletions geode-protobuf-messages/src/main/proto/v1/basicTypes.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,9 @@ message EncodedValue {
float floatResult = 7;
bytes binaryResult = 8;
string stringResult = 9;
CustomEncodedValue customEncodedValue = 50;
}
}

message CustomEncodedValue {
EncodingType encodingType = 1;
bytes value = 2;
}

enum EncodingType {
INVALID = 0;
JSON = 10;
string jsonObjectResult = 10;
}
}

message Region {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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.geode.internal.protocol.operations;

import org.apache.geode.internal.exception.InvalidExecutionContextException;
import org.apache.geode.internal.protocol.MessageExecutionContext;
import org.apache.geode.internal.protocol.Result;
import org.apache.geode.internal.protocol.protobuf.v1.ClientProtocol;
import org.apache.geode.internal.protocol.protobuf.v1.ProtobufSerializationService;
import org.apache.geode.internal.protocol.state.exception.ConnectionStateException;

public interface ProtobufOperationHandler<Req, Resp> extends
OperationHandler<Req, Resp, ClientProtocol.ErrorResponse, ProtobufSerializationService> {
@Override
Result<Resp, ClientProtocol.ErrorResponse> process(
ProtobufSerializationService serializationService, Req request,
MessageExecutionContext messageExecutionContext)
throws InvalidExecutionContextException, ConnectionStateException;
}
Loading

0 comments on commit e24e038

Please sign in to comment.