diff options
Diffstat (limited to 'policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java')
-rw-r--r-- | policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java | 249 |
1 files changed, 249 insertions, 0 deletions
diff --git a/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java new file mode 100644 index 00000000..57976a3e --- /dev/null +++ b/policy-management/src/main/java/org/onap/policy/drools/protocol/coders/GsonProtocolCoderToolset.java @@ -0,0 +1,249 @@ +/* + * ============LICENSE_START======================================================= + * ONAP + * ================================================================================ + * Copyright (C) 2019 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * 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. + * ============LICENSE_END========================================================= + */ + +package org.onap.policy.drools.protocol.coders; + +import com.fasterxml.jackson.annotation.JsonIgnore; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Type; +import java.time.Instant; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import org.onap.policy.common.gson.annotation.GsonJsonIgnore; +import org.onap.policy.drools.controller.DroolsController; +import org.onap.policy.drools.protocol.coders.EventProtocolCoder.CoderFilters; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Tools used for encoding/decoding using GSON. + */ +class GsonProtocolCoderToolset extends ProtocolCoderToolset { + /** + * Logger. + */ + private static final Logger logger = LoggerFactory.getLogger(GsonProtocolCoderToolset.class); + + /** + * Formatter for JSON encoding/decoding. + */ + @JsonIgnore + @GsonJsonIgnore + public static final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSSSSSxxx"); + + @JsonIgnore + @GsonJsonIgnore + public static final DateTimeFormatter zuluFormat = DateTimeFormatter.ISO_INSTANT; + + /** + * Adapter for ZonedDateTime. + */ + public static class GsonUtcAdapter implements JsonSerializer<ZonedDateTime>, JsonDeserializer<ZonedDateTime> { + @Override + public ZonedDateTime deserialize(JsonElement element, Type type, + JsonDeserializationContext context) { + try { + return ZonedDateTime.parse(element.getAsString(), format); + } catch (final Exception e) { + logger.info("GsonUTCAdapter: cannot parse {} because of {}", element, e.getMessage(), e); + } + return null; + } + + @Override + public JsonElement serialize(ZonedDateTime datetime, Type type, + JsonSerializationContext context) { + return new JsonPrimitive(datetime.format(format)); + } + } + + public static class GsonInstantAdapter implements JsonSerializer<Instant>, JsonDeserializer<Instant> { + + @Override + public Instant deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) { + return Instant.ofEpochMilli(json.getAsLong()); + } + + @Override + public JsonElement serialize(Instant src, Type typeOfSrc, JsonSerializationContext context) { + return new JsonPrimitive(src.toEpochMilli()); + } + + } + + + /** + * decoder. + */ + @JsonIgnore + @GsonJsonIgnore + protected final Gson decoder = new GsonBuilder().disableHtmlEscaping() + .registerTypeAdapter(ZonedDateTime.class, new GsonUtcAdapter()) + .registerTypeAdapter(Instant.class, new GsonInstantAdapter()).create(); + + /** + * encoder. + */ + @JsonIgnore + @GsonJsonIgnore + protected final Gson encoder = new GsonBuilder().disableHtmlEscaping() + .registerTypeAdapter(ZonedDateTime.class, new GsonUtcAdapter()) + .registerTypeAdapter(Instant.class, new GsonInstantAdapter()).create(); + + /** + * Toolset to encode/decode tools associated with a topic. + * + * @param eventProtocolParams parameter object for event encoder + * @param controllerId controller id + */ + public GsonProtocolCoderToolset(EventProtocolParams eventProtocolParams, String controllerId) { + super(eventProtocolParams, controllerId); + } + + /** + * gets the Gson decoder. + * + * @return the Gson decoder + */ + @JsonIgnore + @GsonJsonIgnore + protected Gson getDecoder() { + return this.decoder; + } + + /** + * gets the Gson encoder. + * + * @return the Gson encoder + */ + @JsonIgnore + @GsonJsonIgnore + protected Gson getEncoder() { + return this.encoder; + } + + /** + * {@inheritDoc}. + */ + @Override + public Object decode(String json) { + + final DroolsController droolsController = + DroolsController.factory.get(this.groupId, this.artifactId, ""); + if (droolsController == null) { + logger.warn("{}: no drools-controller to process {}", this, json); + throw new IllegalStateException("no drools-controller to process event"); + } + + final CoderFilters decoderFilter = this.filter(json); + if (decoderFilter == null) { + logger.debug("{}: no decoder to process {}", this, json); + throw new UnsupportedOperationException("no decoder to process event"); + } + + Class<?> decoderClass; + try { + decoderClass = droolsController.fetchModelClass(decoderFilter.getCodedClass()); + if (decoderClass == null) { + logger.warn("{}: cannot fetch application class {}", this, decoderFilter.getCodedClass()); + throw new IllegalStateException( + "cannot fetch application class " + decoderFilter.getCodedClass()); + } + } catch (final Exception e) { + logger.warn("{}: cannot fetch application class {} because of {}", this, + decoderFilter.getCodedClass(), e.getMessage()); + throw new UnsupportedOperationException( + "cannot fetch application class " + decoderFilter.getCodedClass(), e); + } + + if (this.customCoder != null) { + try { + final Class<?> gsonClassContainer = + droolsController.fetchModelClass(this.customCoder.getClassContainer()); + final Field gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField); + final Object gsonObject = gsonField.get(null); + final Method fromJsonMethod = gsonObject.getClass().getDeclaredMethod("fromJson", + new Class[] {String.class, Class.class}); + return fromJsonMethod.invoke(gsonObject, json, decoderClass); + } catch (final Exception e) { + logger.warn("{}: cannot fetch application class {} because of {}", this, + decoderFilter.getCodedClass(), e.getMessage()); + throw new UnsupportedOperationException( + "cannot fetch application class " + decoderFilter.getCodedClass(), e); + } + } else { + try { + return this.decoder.fromJson(json, decoderClass); + } catch (final Exception e) { + logger.warn("{} cannot decode {} into {} because of {}", this, json, decoderClass.getName(), + e.getMessage(), e); + throw new UnsupportedOperationException( + "cannont decode into " + decoderFilter.getCodedClass(), e); + } + } + } + + /** + * {@inheritDoc}. + */ + @Override + public String encode(Object event) { + + if (this.customCoder != null) { + try { + final DroolsController droolsController = + DroolsController.factory.get(this.groupId, this.artifactId, null); + final Class<?> gsonClassContainer = + droolsController.fetchModelClass(this.customCoder.getClassContainer()); + final Field gsonField = gsonClassContainer.getField(this.customCoder.staticCoderField); + final Object gsonObject = gsonField.get(null); + final Method toJsonMethod = + gsonObject.getClass().getDeclaredMethod("toJson", new Class[] {Object.class}); + return (String) toJsonMethod.invoke(gsonObject, event); + } catch (final Exception e) { + logger.warn("{} cannot custom-encode {} because of {}", this, event, e.getMessage(), e); + throw new UnsupportedOperationException("event cannot be encoded", e); + } + } else { + try { + return this.encoder.toJson(event); + } catch (final Exception e) { + logger.warn("{} cannot encode {} because of {}", this, event, e.getMessage(), e); + throw new UnsupportedOperationException("event cannot be encoded", e); + } + } + } + + @Override + public String toString() { + final StringBuilder builder = new StringBuilder(); + builder.append("GsonProtocolCoderToolset [toString()=").append(super.toString()).append("]"); + return builder.toString(); + } +} |