Skip to content

Commit

Permalink
Fixes deserialization of enums when using booleans instead of strings (
Browse files Browse the repository at this point in the history
…#482) (#488)

* Fixes deserialization of enums when using booleans instead of strings



* Fixes CHANGELOG.md



* Fixes checkstyle failure



* Include boolean support in existing JsonEnum.Deserializer



---------


(cherry picked from commit 5af5674)

Signed-off-by: Patrick Schlindwein <patrick.schlindwein@bolindalabs.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
1 parent 964be9e commit 4294495
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Inspired from [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
- Fix missing Highlight and SourceConfig in the MultisearchBody ([#442](https://github.com/opensearch-project/opensearch-java/pull/442))
- Fix search failure with missing required property HitsMetadata.total when trackTotalHits is disabled ([#372](https://github.com/opensearch-project/opensearch-java/pull/372))
- Fix failure when deserialing response for tasks API ([#463](https://github.com/opensearch-project/opensearch-java/pull/463))
- Fix failure when deserializing boolean types for enums ([#463](https://github.com/opensearch-project/opensearch-java/pull/482))

### Security

Expand Down
34 changes: 25 additions & 9 deletions java-client/src/main/java/org/opensearch/client/json/JsonEnum.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

/**
* Base interface for enumerations in API types. Members have a JSON representation and also accept
* aliases when parsed from a string value.
* aliases when parsed from a string value. For some enumerations primitive boolean values are also supported.
*/
public interface JsonEnum extends JsonpSerializable {
String jsonValue();
Expand All @@ -62,19 +62,24 @@ default void serialize(JsonGenerator generator, JsonpMapper params) {
class Deserializer<T extends JsonEnum> extends JsonpDeserializerBase<T> {
private final Map<String, T> lookupTable;

private static final EnumSet<JsonParser.Event> ACCEPTED_EVENTS = EnumSet.of(
JsonParser.Event.VALUE_STRING,
JsonParser.Event.KEY_NAME,
JsonParser.Event.VALUE_TRUE,
JsonParser.Event.VALUE_FALSE
);

private static final EnumSet<JsonParser.Event> NATIVE_EVENTS = EnumSet.of(JsonParser.Event.VALUE_STRING);

public Deserializer(T[] values) {
super(
EnumSet.of(JsonParser.Event.VALUE_STRING, JsonParser.Event.KEY_NAME),
EnumSet.of(JsonParser.Event.VALUE_STRING)
);
super(ACCEPTED_EVENTS, NATIVE_EVENTS);

// Use the same size calculation as in java.lang.Enum.enumConstantDirectory
this.lookupTable = new HashMap<>((int)(values.length / 0.75f) + 1);
this.lookupTable = new HashMap<>((int) (values.length / 0.75f) + 1);
for (T member : values) {
this.lookupTable.put(member.jsonValue(), member);
String[] aliases = member.aliases();
if (aliases != null) {
for (String alias: aliases) {
for (String alias : aliases) {
this.lookupTable.put(alias, member);
}
}
Expand All @@ -83,7 +88,18 @@ public Deserializer(T[] values) {

@Override
public T deserialize(JsonParser parser, JsonpMapper mapper, JsonParser.Event event) {
String value = parser.getString();
String value;
switch (event) {
case VALUE_TRUE:
value = "true";
break;
case VALUE_FALSE:
value = "false";
break;
default:
value = parser.getString();
}

return deserialize(value, parser);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,14 @@

package org.opensearch.client.opensearch.model;

import org.junit.Test;
import org.opensearch.client.opensearch._types.Bytes;
import org.opensearch.client.opensearch._types.mapping.DynamicMapping;
import org.opensearch.client.opensearch._types.mapping.GeoOrientation;
import org.junit.Assert;
import org.junit.Test;

import java.util.Arrays;

public class EnumTest extends Assert {
public class EnumTest extends ModelTestCase {

@Test
public void testSimpleEnum() {
Expand All @@ -56,4 +56,16 @@ public void testEnumWithAliases() {
assertEquals(GeoOrientation.Right, GeoOrientation._DESERIALIZER.parse(alias));
});
}

@Test
public void testEnumWithBooleanSupport() {
var booleanAsString = fromJson("\"true\"", DynamicMapping.class);
assertEquals(booleanAsString, DynamicMapping.True);

var nonBooleanEnumValue = fromJson("\"runtime\"", DynamicMapping.class);
assertEquals(nonBooleanEnumValue, DynamicMapping.Runtime);

var booleanPrimitive = fromJson("false", DynamicMapping.class);
assertEquals(booleanPrimitive, DynamicMapping.False);
}
}

0 comments on commit 4294495

Please sign in to comment.