Skip to content

Commit 931fda4

Browse files
committed
Add log entry Payload class and tests
1 parent 48971b2 commit 931fda4

File tree

4 files changed

+732
-0
lines changed

4 files changed

+732
-0
lines changed
Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
/*
2+
* Copyright 2016 Google Inc. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.logging;
18+
19+
import static com.google.common.base.Preconditions.checkNotNull;
20+
21+
import com.google.common.base.MoreObjects;
22+
import com.google.protobuf.Any;
23+
import com.google.protobuf.Struct;
24+
25+
import java.io.Serializable;
26+
import java.util.Map;
27+
import java.util.Objects;
28+
29+
/**
30+
* A base class for log entry payloads.
31+
*
32+
* @see <a href="https://cloud.google.com/logging/docs/view/logs_index">Log Entries and Logs</a>
33+
*/
34+
public abstract class Payload<T> implements Serializable {
35+
36+
private static final long serialVersionUID = -3802834715329130521L;
37+
38+
private final Type type;
39+
private final T data;
40+
41+
/**
42+
* Type for a log entry payload.
43+
*/
44+
public enum Type {
45+
/**
46+
* Log entry data as UTF8 string.
47+
*/
48+
STRING,
49+
50+
/**
51+
* Log entry data as JSON.
52+
*/
53+
JSON,
54+
55+
/**
56+
* Log entry data as a protobuf object.
57+
*/
58+
PROTO
59+
}
60+
61+
/**
62+
* A log entry payload as an UTF-8 string.
63+
*/
64+
public static final class StringPayload extends Payload<String> {
65+
66+
private static final long serialVersionUID = 646595882175676029L;
67+
68+
StringPayload(String data) {
69+
super(Type.STRING, data);
70+
}
71+
72+
@Override
73+
com.google.logging.v2.LogEntry.Builder toPb() {
74+
return com.google.logging.v2.LogEntry.newBuilder().setTextPayload(data());
75+
}
76+
77+
/**
78+
* Creates a log entry payload given its data represented as an UTF-8 string.
79+
*/
80+
public static StringPayload of(String data) {
81+
return new StringPayload(data);
82+
}
83+
84+
static StringPayload fromPb(com.google.logging.v2.LogEntry entryPb) {
85+
return StringPayload.of(entryPb.getTextPayload());
86+
}
87+
}
88+
89+
/**
90+
* A log entry's JSON payload.
91+
*/
92+
public static final class JsonPayload extends Payload<Struct> {
93+
94+
private static final long serialVersionUID = 5747721918608143350L;
95+
96+
JsonPayload(Struct jsonData) {
97+
super(Type.JSON, jsonData);
98+
}
99+
100+
/**
101+
* Returns the log entry's JSON data as an unmodifiable map.
102+
*/
103+
public Map<String, Object> dataAsMap() {
104+
return Structs.asMap(data());
105+
}
106+
107+
@Override
108+
com.google.logging.v2.LogEntry.Builder toPb() {
109+
return com.google.logging.v2.LogEntry.newBuilder().setJsonPayload(data());
110+
}
111+
112+
/**
113+
* Creates a log entry payload given its JSON data represented as a map. The provided map is
114+
* copied into a {@link Struct} object.
115+
*
116+
* <p>Notice that all numbers (int, long, float and double) are serialized as double values.
117+
* Enums are serialized as strings.
118+
*
119+
* <p>Example usage of {@code JsonPayload}:
120+
* <pre>{@code
121+
* List<Long> listValue = Arrays.asList(1L, 2L);
122+
* Map<String, Object> innerMap = new HashMap<String, Object>();
123+
* innerMap.put("booleanValue", true);
124+
* innerMap.put("stringValue", "stringValue");
125+
* Map<String, Object> jsonContent = new HashMap<String, Object>();
126+
* jsonContent.put("listValue", listValue);
127+
* jsonContent.put("integerValue", 42);
128+
* jsonContent.put("doubleValue", 42.0);
129+
* jsonContent.put("stringValue", "stringValue");
130+
* jsonContent.put("mapValue", innerMap);
131+
* JsonPayload payload = JsonPayload.of(jsonContent);
132+
* }</pre>
133+
*/
134+
public static JsonPayload of(Map<String, Object> data) {
135+
return new JsonPayload(Structs.newStruct(data));
136+
}
137+
138+
/**
139+
* Creates a log entry payload given its JSON data represented as a protobuf struct.
140+
*/
141+
public static JsonPayload of(Struct data) {
142+
return new JsonPayload(data);
143+
}
144+
145+
static JsonPayload fromPb(com.google.logging.v2.LogEntry entryPb) {
146+
return JsonPayload.of(entryPb.getJsonPayload());
147+
}
148+
}
149+
150+
/**
151+
* A log entry payload as a protobuf object.
152+
*/
153+
public static final class ProtoPayload extends Payload<Any> {
154+
155+
private static final long serialVersionUID = 155951112369716872L;
156+
157+
ProtoPayload(Any data) {
158+
super(Type.PROTO, data);
159+
}
160+
161+
@Override
162+
com.google.logging.v2.LogEntry.Builder toPb() {
163+
return com.google.logging.v2.LogEntry.newBuilder().setProtoPayload(data());
164+
}
165+
166+
/**
167+
* Creates a log entry payload given its data as a protobuf object.
168+
*/
169+
public static ProtoPayload of(Any data) {
170+
return new ProtoPayload(data);
171+
}
172+
173+
static ProtoPayload fromPb(com.google.logging.v2.LogEntry entryPb) {
174+
return ProtoPayload.of(entryPb.getProtoPayload());
175+
}
176+
}
177+
178+
private Payload(Type type, T data) {
179+
this.type = checkNotNull(type);
180+
this.data = checkNotNull(data);
181+
}
182+
183+
/**
184+
* Returns the payload type. Payload can be an UTF-8 string ({@link Type#STRING}), a JSON object
185+
* ({@link Type#JSON}) or a protobuf object ({@link Type#PROTO}).
186+
*/
187+
public Type type() {
188+
return type;
189+
}
190+
191+
/**
192+
* Returns the log entry payload's data.
193+
*/
194+
public T data() {
195+
return data;
196+
}
197+
198+
@Override
199+
public final boolean equals(Object obj) {
200+
if (obj == this) {
201+
return true;
202+
}
203+
if (obj == null || !(obj instanceof Payload)) {
204+
return false;
205+
}
206+
Payload<?> other = (Payload<?>) obj;
207+
return Objects.equals(type, other.type) && Objects.equals(data, other.data);
208+
}
209+
210+
@Override
211+
public final int hashCode() {
212+
return Objects.hash(type, data);
213+
}
214+
215+
@Override
216+
public String toString() {
217+
return MoreObjects.toStringHelper(this).add("type", type).add("data", data).toString();
218+
}
219+
220+
abstract com.google.logging.v2.LogEntry.Builder toPb();
221+
222+
@SuppressWarnings("unchecked")
223+
static <T extends Payload<?>> T fromPb(com.google.logging.v2.LogEntry entryPb) {
224+
switch (entryPb.getPayloadCase()) {
225+
case TEXT_PAYLOAD:
226+
return (T) StringPayload.fromPb(entryPb);
227+
case JSON_PAYLOAD:
228+
return (T) JsonPayload.fromPb(entryPb);
229+
case PROTO_PAYLOAD:
230+
return (T) ProtoPayload.fromPb(entryPb);
231+
case PAYLOAD_NOT_SET:
232+
return null;
233+
default:
234+
// should never occur
235+
throw new IllegalArgumentException("Unrecognized log entry payload");
236+
}
237+
}
238+
}

0 commit comments

Comments
 (0)