com.canoo.dp.impl.server.event.EventStreamSerializer Maven / Gradle / Ivy
/*
* Copyright 2015-2018 Canoo Engineering AG.
*
* 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.canoo.dp.impl.server.event;
import com.canoo.dp.impl.platform.core.Assert;
import com.canoo.platform.remoting.server.event.MessageEventContext;
import com.canoo.platform.remoting.server.event.Topic;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
import org.apiguardian.api.API;
import java.io.IOException;
import java.io.Serializable;
import java.util.Iterator;
import java.util.Map;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.CONTEXT_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.DATA_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.METADATA_KEY_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.METADATA_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.METADATA_VALUE_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.SPEC_1_0;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.SPEC_VERSION_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.TIMESTAMP_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.TOPIC_PARAM;
import static com.canoo.dp.impl.server.event.DistributedEventConstants.TYPE_ID;
import static org.apiguardian.api.API.Status.INTERNAL;
@API(since = "1.0.0.RC1", status = INTERNAL)
public class EventStreamSerializer implements StreamSerializer> {
private final Gson gson;
private EventStreamSerializer(final Gson gson) {
this.gson = Assert.requireNonNull(gson, "gson");
}
public EventStreamSerializer() {
this(new GsonBuilder().serializeNulls().create());
}
@Override
public void write(final ObjectDataOutput out, final DolphinEvent> event) throws IOException {
out.writeUTF(gson.toJson(convertToJson(event)));
}
private JsonObject convertToJson(final DolphinEvent> event) throws IOException {
final JsonObject root = new JsonObject();
root.addProperty(SPEC_VERSION_PARAM, SPEC_1_0);
final Serializable data = event.getData();
if (data != null) {
root.addProperty(DATA_PARAM, Base64Utils.toBase64(data));
} else {
root.add(DATA_PARAM, JsonNull.INSTANCE);
}
root.add(CONTEXT_PARAM, convertToJson(event.getMessageEventContext()));
return root;
}
private JsonObject convertToJson(final MessageEventContext> eventContext) throws IOException {
final JsonObject root = new JsonObject();
root.addProperty(TOPIC_PARAM, eventContext.getTopic().getName());
root.addProperty(TIMESTAMP_PARAM, eventContext.getTimestamp());
final JsonArray metadataArray = new JsonArray();
for (final Map.Entry entry : eventContext.getMetadata().entrySet()) {
final String key = entry.getKey();
final Serializable data = entry.getValue();
final JsonObject metadataEntry = new JsonObject();
metadataEntry.addProperty(METADATA_KEY_PARAM, key);
if (data != null) {
metadataEntry.addProperty(METADATA_VALUE_PARAM, Base64Utils.toBase64(data));
} else {
metadataEntry.add(METADATA_VALUE_PARAM, JsonNull.INSTANCE);
}
metadataArray.add(metadataEntry);
}
root.add(METADATA_PARAM, metadataArray);
return root;
}
@Override
public DolphinEvent> read(final ObjectDataInput in) throws IOException {
final JsonElement root = new JsonParser().parse(in.readUTF());
if (!root.isJsonObject()) {
throw new IllegalArgumentException("Input can not be parsed!");
}
if (!root.getAsJsonObject().has(CONTEXT_PARAM)) {
throw new IllegalArgumentException("Input can not be parsed! No event context found");
}
if (!root.getAsJsonObject().has(SPEC_VERSION_PARAM) &&
!root.getAsJsonObject().get(SPEC_VERSION_PARAM).isJsonPrimitive() &&
!root.getAsJsonObject().get(SPEC_VERSION_PARAM).getAsJsonPrimitive().isString() &&
!root.getAsJsonObject().get(SPEC_VERSION_PARAM).getAsJsonPrimitive().getAsString().equals(SPEC_1_0)) {
throw new IllegalArgumentException("Input can not be parsed! Unknown Spec");
}
final JsonElement contextElement = root.getAsJsonObject().get(CONTEXT_PARAM);
if (!contextElement.isJsonObject()) {
throw new IllegalArgumentException("Input can not be parsed! event context not parseable");
}
if (!contextElement.getAsJsonObject().has(TOPIC_PARAM) &&
!contextElement.getAsJsonObject().get(TOPIC_PARAM).isJsonPrimitive() &&
!contextElement.getAsJsonObject().get(TOPIC_PARAM).getAsJsonPrimitive().isString()) {
throw new IllegalArgumentException("Input can not be parsed! No topic found");
}
final Topic> topic = new Topic<>(contextElement.getAsJsonObject().getAsJsonPrimitive(TOPIC_PARAM).getAsString());
if (!contextElement.getAsJsonObject().has(TIMESTAMP_PARAM) &&
!contextElement.getAsJsonObject().get(TIMESTAMP_PARAM).isJsonPrimitive() &&
!contextElement.getAsJsonObject().get(TIMESTAMP_PARAM).getAsJsonPrimitive().isNumber()) {
throw new IllegalArgumentException("Input can not be parsed! No timestamp found");
}
final long timestamp = contextElement.getAsJsonObject().getAsJsonPrimitive(TIMESTAMP_PARAM).getAsLong();
if (!root.getAsJsonObject().has(DATA_PARAM)) {
throw new IllegalArgumentException("Input can not be parsed! No data found");
}
final JsonElement dataElement = root.getAsJsonObject().get(DATA_PARAM);
Serializable data;
if (dataElement.isJsonNull()) {
data = null;
} else if (dataElement.isJsonPrimitive() && dataElement.getAsJsonPrimitive().isString()) {
try {
data = Base64Utils.fromBase64(dataElement.getAsJsonPrimitive().getAsString());
} catch (ClassNotFoundException e) {
throw new IllegalArgumentException("Input can not be parsed! Data can not be parsed");
}
} else {
throw new IllegalArgumentException("Input can not be parsed! Data can not be parsed");
}
final DolphinEvent event = new DolphinEvent(topic, timestamp, data);
if (!contextElement.getAsJsonObject().has(METADATA_PARAM)) {
throw new IllegalArgumentException("Input can not be parsed! No metadata found");
}
final JsonElement metadataArrayElement = contextElement.getAsJsonObject().get(METADATA_PARAM);
if (!metadataArrayElement.isJsonArray()) {
throw new IllegalArgumentException("Input can not be parsed! metadata can not be parsed");
}
final Iterator metadataIterator = metadataArrayElement.getAsJsonArray().iterator();
while (metadataIterator.hasNext()) {
final JsonElement metadataElement = metadataIterator.next();
if (!metadataElement.isJsonObject()) {
throw new IllegalArgumentException("Input can not be parsed! metadata can not be parsed");
}
if (!metadataElement.getAsJsonObject().has(METADATA_KEY_PARAM) &&
!metadataElement.getAsJsonObject().get(METADATA_KEY_PARAM).isJsonPrimitive() &&
!metadataElement.getAsJsonObject().get(METADATA_KEY_PARAM).getAsJsonPrimitive().isString()) {
throw new IllegalArgumentException("Input can not be parsed! metadata can not be parsed");
}
final String metadataKey = metadataElement.getAsJsonObject().get(METADATA_KEY_PARAM).getAsJsonPrimitive().getAsString();
if (!metadataElement.getAsJsonObject().has(METADATA_VALUE_PARAM) &&
((metadataElement.getAsJsonObject().get(METADATA_VALUE_PARAM).isJsonPrimitive() &&
metadataElement.getAsJsonObject().get(METADATA_VALUE_PARAM).getAsJsonPrimitive().isString()) || metadataElement.getAsJsonObject().get(METADATA_VALUE_PARAM).isJsonNull())) {
throw new IllegalArgumentException("Input can not be parsed! metadata for key '" + metadataKey + "' can not be parsed");
}
if (metadataElement.getAsJsonObject().get(METADATA_VALUE_PARAM).isJsonNull()) {
event.addMetadata(metadataKey, null);
} else {
try {
event.addMetadata(metadataKey, Base64Utils.fromBase64(metadataElement.getAsJsonObject().get(METADATA_VALUE_PARAM).getAsJsonPrimitive().getAsString()));
} catch (final ClassNotFoundException e) {
throw new IllegalArgumentException("Input can not be parsed! metadata for key '" + metadataKey + "' can not be parsed");
}
}
}
return event;
}
@Override
public int getTypeId() {
return TYPE_ID;
}
@Override
public void destroy() {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy