Skip to content

Commit

Permalink
SDKQE-3406 :- Add custom serializer in seach option
Browse files Browse the repository at this point in the history
1. Add pass serializer search option is custom serializer is set to true
2. Implement a custom serializer
3. check if fields in result are null, then don't parse then according
to the fieldAs input

Change-Id: I498d9d3316a3587e2e925206a931f283fe814c43
Reviewed-on: https://review.couchbase.org/c/couchbase-jvm-clients/+/214786
Reviewed-by: Graham Pople <graham.pople@couchbase.com>
Tested-by: Build Bot <build@couchbase.com>
  • Loading branch information
CosmicSaaurabh committed Sep 10, 2024
1 parent b825e4a commit 9771679
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
import com.couchbase.client.protocol.shared.ContentAs;
import com.couchbase.stream.ReactiveSearchResultStreamer;
import com.couchbase.utils.ContentAsUtil;
import com.couchbase.utils.CustomJsonSerializer;
import com.google.common.primitives.Floats;
import com.google.protobuf.ByteString;
import com.google.protobuf.Timestamp;
Expand Down Expand Up @@ -292,6 +293,13 @@ static SearchOptions convertSearchOptions(boolean hasOptions, com.couchbase.clie
opts.includeLocations(o.getIncludeLocations());
}

if (o.hasSerialize()) {
if (o.getSerialize().hasCustomSerializer() && o.getSerialize().getCustomSerializer()) {
CustomJsonSerializer customSerializer = new CustomJsonSerializer();
opts.serializer(customSerializer);
}
}

return opts;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,13 @@
import java.util.function.Supplier;

public class ContentAsUtil {
private static Try<ContentTypes> getNullContentType(){
return new Try<>(ContentTypes.newBuilder().
setContentAsNull(ContentTypes.NullValue.newBuilder()
.getDefaultInstanceForType()).build()
);
}

public static Try<ContentTypes> contentType(ContentAs contentAs,
Supplier<byte[]> asByteArray,
Supplier<String> asString,
Expand All @@ -35,32 +42,46 @@ public static Try<ContentTypes> contentType(ContentAs contentAs,
Supplier<Double> asDouble) {
try {
if (contentAs.hasAsByteArray()) {
byte[] byteArray = asByteArray.get();
if (byteArray == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsBytes(ByteString.copyFrom(asByteArray.get()))
.setContentAsBytes(ByteString.copyFrom(byteArray))
.build());
} else if (contentAs.hasAsString()) {
String string = asString.get();
if (string == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsString(asString.get())
.setContentAsString(string)
.build());
} else if (contentAs.hasAsJsonObject()) {
JsonObject jsonObject = asJsonObject.get();
if (jsonObject == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsBytes(ByteString.copyFrom(asJsonObject.get().toBytes()))
.setContentAsBytes(ByteString.copyFrom(jsonObject.toBytes()))
.build());
} else if (contentAs.hasAsJsonArray()) {
JsonArray jsonArray = asJsonArray.get();
if (jsonArray == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsBytes(ByteString.copyFrom(asJsonArray.get().toBytes()))
.setContentAsBytes(ByteString.copyFrom(jsonArray.toBytes()))
.build());
} else if (contentAs.getAsBoolean()) {
Boolean bool = asBoolean.get();
if (bool == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsBool(asBoolean.get())
.setContentAsBool(bool)
.build());
} else if (contentAs.hasAsInteger()) {
Integer integer = asInteger.get();
if (integer == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsInt64(asInteger.get())
.setContentAsInt64(integer)
.build());
} else if (contentAs.hasAsFloatingPoint()) {
Double dbl = asDouble.get();
if (dbl == null) return getNullContentType();
return new Try<>(ContentTypes.newBuilder()
.setContentAsDouble(asDouble.get())
.setContentAsDouble(dbl)
.build());
} else {
throw new UnsupportedOperationException("Java performer cannot handle contentAs " + contentAs.toString());
Expand All @@ -81,31 +102,44 @@ public static Try<List<ContentTypes>> contentTypeList(ContentAs contentAs,
try {
if (contentAs.hasAsByteArray()) {
return new Try<>(asByteArray.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v)).build())
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v)).build()
: getNullContentType().value())
.toList());
} else if (contentAs.hasAsString()) {
return new Try<>(asString.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsString(v).build())
.toList());
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsString(v).build()
: getNullContentType().value()).toList());
} else if (contentAs.hasAsJsonObject()) {
return new Try<>(asJsonObject.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v.toBytes())).build())
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v.toBytes())).build()
: getNullContentType().value())
.toList());
} else if (contentAs.hasAsJsonArray()) {
return new Try<>(asJsonArray.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v.toBytes())).build())
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsBytes(ByteString.copyFrom(v.toBytes())).build()
: getNullContentType().value())
.toList());
} else if (contentAs.getAsBoolean()) {
return new Try<>(asBoolean.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsBool(v).build())
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsBool(v).build()
: getNullContentType().value())
.toList());
} else if (contentAs.hasAsInteger()) {
return new Try<>(asInteger.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsInt64(v).build())
.map(v -> v != null
? ContentTypes.newBuilder().setContentAsInt64(v).build()
: getNullContentType().value())
.toList());
} else if (contentAs.hasAsFloatingPoint()) {
return new Try<>(asDouble.get().stream()
.map(v -> ContentTypes.newBuilder().setContentAsDouble(v).build())
.map(v -> v != null
?ContentTypes.newBuilder().setContentAsDouble(v).build()
: getNullContentType().value())
.toList());
} else {
throw new UnsupportedOperationException("Java performer cannot handle contentAs " + contentAs.toString());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* CustomJsonSerializer provides a generic implementation of the JsonSerializer interface.
* This serializer is designed to handle the conversion of Java objects to JSON format
* and back, with an additional boolean flag (`Serialized`) that indicates whether
* the object has been serialized. The flag is included in the JSON payload, making
* it easy to track the serialization state of objects.
* Use Cases:
* - This serializer can be used in scenarios where you need to serialize and deserialize
* objects while keeping track of their serialization state.
* Limitations:
* - The current implementation assumes that the input objects can be serialized into
* a JSON format using Jackson's ObjectMapper. Complex or non-standard objects may
* require additional handling.
* - The `deserialize` methods in this implementation modify the original JSON object
* by setting the `Serialized` flag to `false`, which might not be suitable for
* all use cases.
*/

package com.couchbase.utils;

import com.couchbase.client.core.deps.com.fasterxml.jackson.core.JsonProcessingException;
import com.couchbase.client.core.error.DecodingFailureException;
import com.couchbase.client.core.json.Mapper;
import com.couchbase.client.java.codec.JsonSerializer;
import com.couchbase.client.java.codec.TypeRef;
import com.couchbase.client.java.json.JsonObject;


public class CustomJsonSerializer implements JsonSerializer {
@Override
public byte[] serialize(Object input) {
try {
String json = Mapper.writer().writeValueAsString(input);
var obj = JsonObject.create().put("Serialized", true);
return obj.toBytes();
} catch (JsonProcessingException e) {
throw new DecodingFailureException(e);
}
}

@Override
public <T> T deserialize(Class<T> target, byte[] input) {
JsonObject obj = JsonObject.fromJson(input);
obj.put("Serialized", false);
return (T) obj;
}

@Override
public <T> T deserialize(TypeRef<T> target, byte[] input) {
JsonObject obj = JsonObject.fromJson(input);
obj.put("Serialized", false);
return (T) obj;
}
}

0 comments on commit 9771679

Please sign in to comment.