diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/Payload.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/Payload.java index a80262f75..9e86b50bb 100644 --- a/google-cloud-logging/src/main/java/com/google/cloud/logging/Payload.java +++ b/google-cloud-logging/src/main/java/com/google/cloud/logging/Payload.java @@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull; +import com.google.cloud.Structs; import com.google.common.base.MoreObjects; import com.google.protobuf.Any; import com.google.protobuf.Struct; diff --git a/google-cloud-logging/src/main/java/com/google/cloud/logging/Structs.java b/google-cloud-logging/src/main/java/com/google/cloud/logging/Structs.java deleted file mode 100644 index 46ba567e6..000000000 --- a/google-cloud-logging/src/main/java/com/google/cloud/logging/Structs.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright 2016 Google LLC - * - * Licensed 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 com.google.cloud.logging; - -import static com.google.common.base.Preconditions.checkNotNull; - -import com.google.api.client.util.Types; -import com.google.common.collect.Iterables; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.protobuf.ListValue; -import com.google.protobuf.NullValue; -import com.google.protobuf.Struct; -import com.google.protobuf.Value; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -/** - * This class contains static utility methods that operate on or return protobuf's {@code Struct} - * objects. - */ -final class Structs { - - private Structs() {} - - /** - * This class wraps a protobuf's {@code Struct} object and offers a map interface to it, hiding - * protobuf types. - */ - private static final class StructMap extends AbstractMap { - - private final Set> entrySet; - - private StructMap(Struct struct) { - this.entrySet = new StructSet(struct); - } - - private static final class StructSet extends AbstractSet> { - - private static Entry valueToObject(Entry entry) { - return new AbstractMap.SimpleEntry<>( - entry.getKey(), Structs.valueToObject(entry.getValue())); - } - - private final Struct struct; - - private StructSet(Struct struct) { - this.struct = struct; - } - - @Override - public Iterator> iterator() { - return Iterators.transform( - struct.getFieldsMap().entrySet().iterator(), StructSet::valueToObject); - } - - @Override - public int size() { - return struct.getFieldsMap().size(); - } - } - - @Override - public Set> entrySet() { - return entrySet; - } - } - - /** Returns an unmodifiable map view of the {@link Struct} parameter. */ - static Map asMap(Struct struct) { - return new StructMap(checkNotNull(struct)); - } - - /** - * Creates a new {@link Struct} object given the content of the provided {@code map} parameter. - * - *

Notice that all numbers (int, long, float and double) are serialized as double values. Enums - * are serialized as strings. - */ - static Struct newStruct(Map map) { - Map valueMap = Maps.transformValues(checkNotNull(map), Structs::objectToValue); - return Struct.newBuilder().putAllFields(valueMap).build(); - } - - private static Object valueToObject(Value value) { - switch (value.getKindCase()) { - case NULL_VALUE: - return null; - case NUMBER_VALUE: - return value.getNumberValue(); - case STRING_VALUE: - return value.getStringValue(); - case BOOL_VALUE: - return value.getBoolValue(); - case STRUCT_VALUE: - return new StructMap(value.getStructValue()); - case LIST_VALUE: - return Lists.transform(value.getListValue().getValuesList(), Structs::valueToObject); - default: - throw new IllegalArgumentException(String.format("Unsupported protobuf value %s", value)); - } - } - - @SuppressWarnings("unchecked") - private static Value objectToValue(final Object obj) { - Value.Builder builder = Value.newBuilder(); - if (obj == null) { - builder.setNullValue(NullValue.NULL_VALUE); - return builder.build(); - } - Class objClass = obj.getClass(); - if (obj instanceof String) { - builder.setStringValue((String) obj); - } else if (obj instanceof Number) { - builder.setNumberValue(((Number) obj).doubleValue()); - } else if (obj instanceof Boolean) { - builder.setBoolValue((Boolean) obj); - } else if (obj instanceof Iterable || objClass.isArray()) { - builder.setListValue( - ListValue.newBuilder() - .addAllValues(Iterables.transform(Types.iterableOf(obj), Structs::objectToValue))); - } else if (objClass.isEnum()) { - builder.setStringValue(((Enum) obj).name()); - } else if (obj instanceof Map) { - Map map = (Map) obj; - builder.setStructValue(newStruct(map)); - } else { - throw new IllegalArgumentException(String.format("Unsupported protobuf value %s", obj)); - } - return builder.build(); - } -} diff --git a/google-cloud-logging/src/test/java/com/google/cloud/logging/StructsTest.java b/google-cloud-logging/src/test/java/com/google/cloud/logging/StructsTest.java deleted file mode 100644 index b2654a735..000000000 --- a/google-cloud-logging/src/test/java/com/google/cloud/logging/StructsTest.java +++ /dev/null @@ -1,210 +0,0 @@ -/* - * Copyright 2016 Google LLC - * - * Licensed 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 com.google.cloud.logging; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.protobuf.ListValue; -import com.google.protobuf.NullValue; -import com.google.protobuf.Struct; -import com.google.protobuf.Value; -import java.util.HashMap; -import java.util.Map; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -@RunWith(JUnit4.class) -public class StructsTest { - - private static final Double NUMBER = 42.0; - private static final String STRING = "string"; - private static final Boolean BOOLEAN = true; - private static final ImmutableList LIST = - ImmutableList.of(NUMBER, STRING, BOOLEAN); - private static final Map INNER_MAP = new HashMap<>(); - private static final Map MAP = new HashMap<>(); - private static final Value NULL_VALUE = - Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build(); - private static final Value NUMBER_VALUE = Value.newBuilder().setNumberValue(NUMBER).build(); - private static final Value STRING_VALUE = Value.newBuilder().setStringValue(STRING).build(); - private static final Value BOOLEAN_VALUE = Value.newBuilder().setBoolValue(BOOLEAN).build(); - private static final ListValue PROTO_LIST = - ListValue.newBuilder() - .addAllValues(ImmutableList.of(NUMBER_VALUE, STRING_VALUE, BOOLEAN_VALUE)) - .build(); - private static final Value LIST_VALUE = Value.newBuilder().setListValue(PROTO_LIST).build(); - private static final Struct INNER_STRUCT = - Struct.newBuilder() - .putAllFields( - ImmutableMap.of( - "null", NULL_VALUE, - "number", NUMBER_VALUE, - "string", STRING_VALUE, - "boolean", BOOLEAN_VALUE, - "list", LIST_VALUE)) - .build(); - private static final Value STRUCT_VALUE = Value.newBuilder().setStructValue(INNER_STRUCT).build(); - private static final ImmutableMap VALUE_MAP = - ImmutableMap.builder() - .put("null", NULL_VALUE) - .put("number", NUMBER_VALUE) - .put("string", STRING_VALUE) - .put("boolean", BOOLEAN_VALUE) - .put("list", LIST_VALUE) - .put("struct", STRUCT_VALUE) - .buildOrThrow(); - private static final Struct STRUCT = Struct.newBuilder().putAllFields(VALUE_MAP).build(); - private static final ImmutableMap EMPTY_MAP = ImmutableMap.of(); - - @BeforeClass - public static void beforeClass() { - INNER_MAP.put("null", null); - INNER_MAP.put("number", NUMBER); - INNER_MAP.put("string", STRING); - INNER_MAP.put("boolean", BOOLEAN); - INNER_MAP.put("list", LIST); - MAP.put("null", null); - MAP.put("number", NUMBER); - MAP.put("string", STRING); - MAP.put("boolean", BOOLEAN); - MAP.put("list", LIST); - MAP.put("struct", INNER_MAP); - } - - private void checkMapField(Map map, String key, T expected) { - assertThat(map).containsKey(key); - assertThat(map).containsEntry(key, expected); - } - - private void checkStructField(Struct struct, String key, Value expected) { - Map map = struct.getFieldsMap(); - checkMapField(map, key, expected); - } - - @Test - public void testAsMap() { - Map map = Structs.asMap(STRUCT); - checkMapField(map, "null", null); - checkMapField(map, "number", NUMBER); - checkMapField(map, "string", STRING); - checkMapField(map, "boolean", BOOLEAN); - checkMapField(map, "list", LIST); - checkMapField(map, "struct", INNER_MAP); - assertEquals(MAP, map); - } - - @Test - public void testAsMapPut() { - Map map = Structs.asMap(STRUCT); - try { - map.put("key", "value"); - fail(); - } catch (UnsupportedOperationException expected) { - - } - } - - @Test - public void testAsMapRemove() { - Map map = Structs.asMap(STRUCT); - try { - map.remove("null"); - fail(); - } catch (UnsupportedOperationException expected) { - - } - } - - @Test - public void testAsMapEmpty() { - Map map = Structs.asMap(Struct.getDefaultInstance()); - assertThat(map).isEmpty(); - assertEquals(EMPTY_MAP, map); - } - - @Test - public void testAsMapNull() { - try { - Structs.asMap(null); - fail(); - } catch (NullPointerException expected) { - } - } - - @Test - public void testNewStruct() { - Struct struct = Structs.newStruct(MAP); - checkStructField(struct, "null", NULL_VALUE); - checkStructField(struct, "number", NUMBER_VALUE); - checkStructField(struct, "string", STRING_VALUE); - checkStructField(struct, "boolean", BOOLEAN_VALUE); - checkStructField(struct, "list", LIST_VALUE); - checkStructField(struct, "struct", STRUCT_VALUE); - assertEquals(STRUCT, struct); - } - - @Test - public void testNewStructEmpty() { - Struct struct = Structs.newStruct(EMPTY_MAP); - assertThat(struct.getFieldsMap()).isEmpty(); - } - - @Test - public void testNewStructNull() { - try { - Structs.newStruct(null); - fail(); - } catch (NullPointerException expected) { - } - } - - @Test - public void testNumbers() { - int intNumber = Integer.MIN_VALUE; - long longNumber = Long.MAX_VALUE; - float floatNumber = Float.MIN_VALUE; - double doubleNumber = Double.MAX_VALUE; - ImmutableMap map = - ImmutableMap.of( - "int", intNumber, "long", longNumber, "float", floatNumber, "double", doubleNumber); - Struct struct = Structs.newStruct(map); - checkStructField(struct, "int", Value.newBuilder().setNumberValue(intNumber).build()); - checkStructField( - struct, "long", Value.newBuilder().setNumberValue((double) longNumber).build()); - checkStructField(struct, "float", Value.newBuilder().setNumberValue(floatNumber).build()); - checkStructField(struct, "double", Value.newBuilder().setNumberValue(doubleNumber).build()); - Map convertedMap = Structs.asMap(struct); - assertThat(convertedMap.get("int")).isInstanceOf(Double.class); - assertThat(convertedMap.get("long")).isInstanceOf(Double.class); - assertThat(convertedMap.get("float")).isInstanceOf(Double.class); - assertThat(convertedMap.get("double")).isInstanceOf(Double.class); - int convertedInteger = ((Double) convertedMap.get("int")).intValue(); - long convertedLong = ((Double) convertedMap.get("long")).longValue(); - float convertedFloat = ((Double) convertedMap.get("float")).floatValue(); - double convertedDouble = (Double) convertedMap.get("double"); - assertEquals(intNumber, convertedInteger); - assertEquals(longNumber, convertedLong); - assertEquals(floatNumber, convertedFloat, 0); - assertEquals(doubleNumber, convertedDouble, 0); - } -} diff --git a/pom.xml b/pom.xml index 2144bf5a0..b906d687b 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,7 @@ com.google.cloud google-cloud-shared-dependencies - 3.20.0 + 3.21.0 pom import