Java tutorial
/* * Copyright 2015-2016 Red Hat, Inc. and/or its affiliates * and other contributors as indicated by the @author tags. * * 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 org.hawkular.alerts.api.json; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import org.hawkular.alerts.api.model.action.Action; import org.hawkular.alerts.api.model.condition.AvailabilityCondition; import org.hawkular.alerts.api.model.condition.AvailabilityConditionEval; import org.hawkular.alerts.api.model.condition.CompareCondition; import org.hawkular.alerts.api.model.condition.CompareConditionEval; import org.hawkular.alerts.api.model.condition.Condition; import org.hawkular.alerts.api.model.condition.ConditionEval; import org.hawkular.alerts.api.model.condition.EventCondition; import org.hawkular.alerts.api.model.condition.EventConditionEval; import org.hawkular.alerts.api.model.condition.ExternalCondition; import org.hawkular.alerts.api.model.condition.ExternalConditionEval; import org.hawkular.alerts.api.model.condition.RateCondition; import org.hawkular.alerts.api.model.condition.RateConditionEval; import org.hawkular.alerts.api.model.condition.StringCondition; import org.hawkular.alerts.api.model.condition.StringConditionEval; import org.hawkular.alerts.api.model.condition.ThresholdCondition; import org.hawkular.alerts.api.model.condition.ThresholdConditionEval; import org.hawkular.alerts.api.model.condition.ThresholdRangeCondition; import org.hawkular.alerts.api.model.condition.ThresholdRangeConditionEval; import org.hawkular.alerts.api.model.data.AvailabilityType; import org.hawkular.alerts.api.model.event.Alert; import org.hawkular.alerts.api.model.event.Event; import org.hawkular.alerts.api.model.event.Thin; import org.hawkular.alerts.api.model.trigger.Mode; import com.fasterxml.jackson.core.JsonLocation; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.ObjectCodec; import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.deser.BeanDeserializerBuilder; import com.fasterxml.jackson.databind.deser.BeanDeserializerModifier; import com.fasterxml.jackson.databind.introspect.BeanPropertyDefinition; /** * @author Lucas Ponce */ public class JacksonDeserializer { public static class ConditionDeserializer extends JsonDeserializer<Condition> { @Override public Condition deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectCodec objectCodec = jp.getCodec(); JsonNode node = objectCodec.readTree(jp); if (null == node) { throw new ConditionException("Unexpected null node."); } return deserializeCondition(node); } } public static class ConditionEvalDeserializer extends JsonDeserializer<ConditionEval> { @Override public ConditionEval deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException { ObjectCodec objectCodec = jp.getCodec(); JsonNode node = objectCodec.readTree(jp); if (null == node) { throw new ConditionEvalException("Unexpected null node."); } ConditionEval conditionEval = null; JsonNode conditionNode = node.get("condition"); Condition condition = deserializeCondition(conditionNode); switch (condition.getType()) { case AVAILABILITY: { try { conditionEval = new AvailabilityConditionEval(); AvailabilityConditionEval aConditionEval = (AvailabilityConditionEval) conditionEval; aConditionEval.setCondition((AvailabilityCondition) condition); if (node.get("value") != null) { aConditionEval.setValue(AvailabilityType.valueOf(node.get("value").textValue())); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case COMPARE: { try { conditionEval = new CompareConditionEval(); CompareConditionEval cConditionEval = (CompareConditionEval) conditionEval; cConditionEval.setCondition((CompareCondition) condition); if (node.get("value1") != null) { cConditionEval.setValue1(node.get("value1").doubleValue()); } if (node.get("value2") != null) { cConditionEval.setValue2(node.get("value2").doubleValue()); } if (node.get("context2") != null) { cConditionEval.setContext2(deserializeMap(node.get("context2"))); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case EVENT: { try { conditionEval = new EventConditionEval(); EventConditionEval evConditionEval = (EventConditionEval) conditionEval; evConditionEval.setCondition((EventCondition) condition); if (node.get("value") != null) { evConditionEval.setValue(node.get("value").traverse(objectCodec).readValueAs(Event.class)); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case EXTERNAL: { try { conditionEval = new ExternalConditionEval(); ExternalConditionEval eConditionEval = (ExternalConditionEval) conditionEval; eConditionEval.setCondition((ExternalCondition) condition); if (node.get("value") != null) { eConditionEval.setValue(node.get("value").textValue()); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case RATE: { try { conditionEval = new RateConditionEval(); RateConditionEval rConditionEval = (RateConditionEval) conditionEval; rConditionEval.setCondition((RateCondition) condition); if (node.get("time") != null) { rConditionEval.setTime(node.get("time").longValue()); } if (node.get("value") != null) { rConditionEval.setValue(node.get("value").doubleValue()); } if (node.get("previousTime") != null) { rConditionEval.setPreviousTime(node.get("previousTime").longValue()); } if (node.get("previousValue") != null) { rConditionEval.setPreviousValue(node.get("previousValue").doubleValue()); } if (node.get("rate") != null) { rConditionEval.setRate(node.get("rate").doubleValue()); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case RANGE: { try { conditionEval = new ThresholdRangeConditionEval(); ThresholdRangeConditionEval rConditionEval = (ThresholdRangeConditionEval) conditionEval; rConditionEval.setCondition((ThresholdRangeCondition) condition); if (node.get("value") != null) { rConditionEval.setValue(node.get("value").doubleValue()); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case STRING: { try { conditionEval = new StringConditionEval(); StringConditionEval sConditionEval = (StringConditionEval) conditionEval; sConditionEval.setCondition((StringCondition) condition); if (node.get("value") != null) { sConditionEval.setValue(node.get("value").textValue()); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } case THRESHOLD: { try { conditionEval = new ThresholdConditionEval(); ThresholdConditionEval tConditionEval = (ThresholdConditionEval) conditionEval; tConditionEval.setCondition((ThresholdCondition) condition); if (node.get("value") != null) { tConditionEval.setValue(node.get("value").doubleValue()); } } catch (Exception e) { throw new ConditionEvalException(e); } break; } default: { throw new ConditionEvalException("Unexpected Condition type [" + condition.getType().name() + "]"); } } if (conditionEval != null) { try { if (node.get("match") != null) { conditionEval.setMatch(node.get("match").booleanValue()); } if (node.get("evalTimestamp") != null) { conditionEval.setEvalTimestamp(node.get("evalTimestamp").longValue()); } if (node.get("dataTimestamp") != null) { conditionEval.setDataTimestamp(node.get("dataTimestamp").longValue()); } if (node.get("context") != null) { conditionEval.setContext(deserializeMap(node.get("context"))); } } catch (Exception e) { throw new ConditionEvalException(e); } } return conditionEval; } } public static Condition deserializeCondition(JsonNode node) throws JsonProcessingException { if (node == null) { return null; } Condition condition = null; Condition.Type conditionType = null; if (node.get("type") == null) { throw new ConditionException("Condition must have a type"); } try { conditionType = Condition.Type.valueOf(node.get("type").asText().toUpperCase()); } catch (Exception e) { throw new ConditionException(e); } switch (conditionType) { case THRESHOLD: { try { condition = new ThresholdCondition(); ThresholdCondition tCondition = (ThresholdCondition) condition; if (node.get("dataId") != null) { tCondition.setDataId(node.get("dataId").textValue()); } if (node.get("operator") != null) { tCondition.setOperator(ThresholdCondition.Operator.valueOf(node.get("operator").textValue())); } if (node.get("threshold") != null) { tCondition.setThreshold(node.get("threshold").doubleValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case AVAILABILITY: { try { condition = new AvailabilityCondition(); AvailabilityCondition aCondition = (AvailabilityCondition) condition; if (node.get("dataId") != null) { aCondition.setDataId(node.get("dataId").textValue()); } if (node.get("operator") != null) { aCondition .setOperator(AvailabilityCondition.Operator.valueOf(node.get("operator").textValue())); } } catch (Exception e) { throw new ConditionException(e); } break; } case COMPARE: { try { condition = new CompareCondition(); CompareCondition cCondition = (CompareCondition) condition; if (node.get("dataId") != null) { cCondition.setDataId(node.get("dataId").textValue()); } if (node.get("operator") != null) { cCondition.setOperator(CompareCondition.Operator.valueOf(node.get("operator").textValue())); } if (node.get("data2Id") != null) { cCondition.setData2Id(node.get("data2Id").textValue()); } if (node.get("data2Multiplier") != null) { cCondition.setData2Multiplier(node.get("data2Multiplier").doubleValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case RANGE: { try { condition = new ThresholdRangeCondition(); ThresholdRangeCondition rCondition = (ThresholdRangeCondition) condition; if (node.get("dataId") != null) { rCondition.setDataId(node.get("dataId").textValue()); } if (node.get("operatorLow") != null) { rCondition.setOperatorLow( ThresholdRangeCondition.Operator.valueOf(node.get("operatorLow").textValue())); } if (node.get("operatorHigh") != null) { rCondition.setOperatorHigh( ThresholdRangeCondition.Operator.valueOf(node.get("operatorHigh").textValue())); } if (node.get("thresholdLow") != null) { rCondition.setThresholdLow(node.get("thresholdLow").doubleValue()); } if (node.get("thresholdHigh") != null) { rCondition.setThresholdHigh(node.get("thresholdHigh").doubleValue()); } if (node.get("inRange") != null) { rCondition.setInRange(node.get("inRange").booleanValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case STRING: { try { condition = new StringCondition(); StringCondition sCondition = (StringCondition) condition; if (node.get("dataId") != null) { sCondition.setDataId(node.get("dataId").textValue()); } if (node.get("operator") != null) { sCondition.setOperator(StringCondition.Operator.valueOf(node.get("operator").textValue())); } if (node.get("pattern") != null) { sCondition.setPattern(node.get("pattern").textValue()); } if (node.get("ignoreCase") != null) { sCondition.setIgnoreCase(node.get("ignoreCase").booleanValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case EXTERNAL: { try { condition = new ExternalCondition(); ExternalCondition eCondition = (ExternalCondition) condition; if (node.get("systemId") != null) { eCondition.setSystemId(node.get("systemId").textValue()); } if (node.get("dataId") != null) { eCondition.setDataId(node.get("dataId").textValue()); } if (node.get("expression") != null) { eCondition.setExpression(node.get("expression").textValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case EVENT: { try { condition = new EventCondition(); EventCondition evCondition = (EventCondition) condition; if (node.get("dataId") != null) { evCondition.setDataId(node.get("dataId").textValue()); } if (node.get("expression") != null) { evCondition.setExpression(node.get("expression").textValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } case RATE: { try { condition = new RateCondition(); RateCondition rCondition = (RateCondition) condition; if (node.get("dataId") != null) { rCondition.setDataId(node.get("dataId").textValue()); } if (node.get("direction") != null) { rCondition.setDirection(RateCondition.Direction.valueOf(node.get("direction").textValue())); } if (node.get("period") != null) { rCondition.setPeriod(RateCondition.Period.valueOf(node.get("period").textValue())); } if (node.get("operator") != null) { rCondition.setOperator(RateCondition.Operator.valueOf(node.get("operator").textValue())); } if (node.get("threshold") != null) { rCondition.setThreshold(node.get("threshold").doubleValue()); } } catch (Exception e) { throw new ConditionException(e); } break; } default: throw new ConditionException("Unexpected Condition Type [" + conditionType.name() + "]"); } if (condition != null) { try { if (node.get("tenantId") != null) { condition.setTenantId(node.get("tenantId").textValue()); } if (node.get("triggerId") != null) { condition.setTriggerId(node.get("triggerId").textValue()); } if (node.get("triggerMode") != null) { condition.setTriggerMode(Mode.valueOf(node.get("triggerMode").textValue())); } if (node.get("conditionSetSize") != null) { condition.setConditionSetSize(node.get("conditionSetSize").intValue()); } if (node.get("conditionSetIndex") != null) { condition.setConditionSetIndex(node.get("conditionSetIndex").intValue()); } if (node.get("context") != null) { condition.setContext(deserializeMap(node.get("context"))); } } catch (Exception e) { throw new ConditionException(e); } } return condition; } public static Map<String, String> deserializeMap(JsonNode mapNode) { Map<String, String> map = new HashMap<>(); Iterator<String> fieldNames = mapNode.fieldNames(); while (fieldNames.hasNext()) { String field = fieldNames.next(); map.put(field, mapNode.get(field).asText()); } return map; } public static class ConditionException extends JsonProcessingException { private static final long serialVersionUID = 1L; protected ConditionException(String msg, JsonLocation loc, Throwable rootCause) { super(msg, loc, rootCause); } protected ConditionException(String msg) { super(msg); } protected ConditionException(String msg, JsonLocation loc) { super(msg, loc); } protected ConditionException(String msg, Throwable rootCause) { super(msg, rootCause); } protected ConditionException(Throwable rootCause) { super(rootCause); } } public static class ConditionEvalException extends JsonProcessingException { private static final long serialVersionUID = 1L; protected ConditionEvalException(String msg, JsonLocation loc, Throwable rootCause) { super(msg, loc, rootCause); } protected ConditionEvalException(String msg) { super(msg); } protected ConditionEvalException(String msg, JsonLocation loc) { super(msg, loc); } protected ConditionEvalException(String msg, Throwable rootCause) { super(msg, rootCause); } protected ConditionEvalException(Throwable rootCause) { super(rootCause); } } public static class AlertThinDeserializer extends BeanDeserializerModifier { List<String> ignorables = new ArrayList<>(); public AlertThinDeserializer() { for (Class clazz = Alert.class; (null != clazz); clazz = clazz.getSuperclass()) { for (Field field : clazz.getDeclaredFields()) { if (field.isAnnotationPresent(Thin.class)) { ignorables.add(field.getName()); } } } for (Field field : Action.class.getDeclaredFields()) { if (field.isAnnotationPresent(Thin.class)) { ignorables.add(field.getName()); } } } @Override public BeanDeserializerBuilder updateBuilder(DeserializationConfig config, BeanDescription beanDesc, BeanDeserializerBuilder builder) { if (!beanDesc.getBeanClass().equals(Alert.class) && !beanDesc.getBeanClass().equals(Action.class)) { return builder; } for (String ignore : ignorables) { builder.addIgnorable(ignore); } return builder; } @Override public List<BeanPropertyDefinition> updateProperties(DeserializationConfig config, BeanDescription beanDesc, List<BeanPropertyDefinition> propDefs) { if (!beanDesc.getBeanClass().equals(Alert.class) && !beanDesc.getBeanClass().equals(Action.class)) { return propDefs; } List<BeanPropertyDefinition> newPropDefs = new ArrayList<>(); for (BeanPropertyDefinition propDef : propDefs) { if (!ignorables.contains(propDef.getName())) { newPropDefs.add(propDef); } } return newPropDefs; } } }