| /** |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 org.apache.atlas.notification; |
| |
| import com.google.gson.Gson; |
| import org.slf4j.Logger; |
| |
| import java.lang.reflect.ParameterizedType; |
| import java.lang.reflect.Type; |
| |
| /** |
| * Deserializer that works with versioned messages. The version of each deserialized message is checked against an |
| * expected version. |
| */ |
| public abstract class VersionedMessageDeserializer<T> implements MessageDeserializer<T> { |
| |
| public static final String VERSION_MISMATCH_MSG = |
| "Notification message version mismatch. Expected %s but recieved %s. Message %s"; |
| |
| private final Type versionedMessageType; |
| private final MessageVersion expectedVersion; |
| private final Logger notificationLogger; |
| private final Gson gson; |
| |
| |
| // ----- Constructors ---------------------------------------------------- |
| |
| /** |
| * Create a versioned message deserializer. |
| * |
| * @param versionedMessageType the type of the versioned message |
| * @param expectedVersion the expected message version |
| * @param gson JSON serialization/deserialization |
| * @param notificationLogger logger for message version mismatch |
| */ |
| public VersionedMessageDeserializer(Type versionedMessageType, MessageVersion expectedVersion, |
| Gson gson, Logger notificationLogger) { |
| this.versionedMessageType = versionedMessageType; |
| this.expectedVersion = expectedVersion; |
| this.gson = gson; |
| this.notificationLogger = notificationLogger; |
| } |
| |
| |
| // ----- MessageDeserializer --------------------------------------------- |
| |
| @Override |
| public T deserialize(String messageJson) { |
| VersionedMessage<T> versionedMessage = gson.fromJson(messageJson, versionedMessageType); |
| |
| // older style messages not wrapped with VersionedMessage |
| if (versionedMessage.getVersion() == null) { |
| Type t = ((ParameterizedType) versionedMessageType).getActualTypeArguments()[0]; |
| versionedMessage = new VersionedMessage<>(MessageVersion.NO_VERSION, gson.<T>fromJson(messageJson, t)); |
| } |
| checkVersion(versionedMessage, messageJson); |
| |
| return versionedMessage.getMessage(); |
| } |
| |
| |
| // ----- helper methods -------------------------------------------------- |
| |
| /** |
| * Check the message version against the expected version. |
| * |
| * @param versionedMessage the versioned message |
| * @param messageJson the notification message json |
| * |
| * @throws IncompatibleVersionException if the message version is incompatable with the expected version |
| */ |
| protected void checkVersion(VersionedMessage<T> versionedMessage, String messageJson) { |
| int comp = versionedMessage.compareVersion(expectedVersion); |
| |
| // message has newer version |
| if (comp > 0) { |
| String msg = |
| String.format(VERSION_MISMATCH_MSG, expectedVersion, versionedMessage.getVersion(), messageJson); |
| notificationLogger.error(msg); |
| throw new IncompatibleVersionException(msg); |
| } |
| |
| // message has older version |
| if (comp < 0) { |
| notificationLogger.info(String.format(VERSION_MISMATCH_MSG, expectedVersion, versionedMessage.getVersion(), |
| messageJson)); |
| } |
| } |
| } |