com.spotify.ffwd.riemann.RiemannSerialization.java Source code

Java tutorial

Introduction

Here is the source code for com.spotify.ffwd.riemann.RiemannSerialization.java

Source

/*-
 * -\-\-
 * FastForward Riemann Module
 * --
 * Copyright (C) 2016 - 2018 Spotify AB
 * --
 * 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.spotify.ffwd.riemann;

import com.aphyr.riemann.Proto;
import com.google.common.collect.ImmutableList;
import com.spotify.ffwd.model.Event;
import com.spotify.ffwd.model.Metric;
import com.spotify.ffwd.protobuf250.InvalidProtocolBufferException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;
import io.netty.buffer.Unpooled;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RiemannSerialization {
    public Proto.Msg parse0(ByteBuf buffer) throws IOException {
        final InputStream inputStream = new ByteBufInputStream(buffer);

        try {
            return Proto.Msg.parseFrom(inputStream);
        } catch (final InvalidProtocolBufferException e) {
            throw new IOException("Invalid protobuf message", e);
        }
    }

    public List<Object> decode0(Proto.Msg message) throws IOException {
        final List<com.aphyr.riemann.Proto.Event> source = message.getEventsList();

        if (source.isEmpty()) {
            return ImmutableList.of();
        }

        final List<Object> events = new ArrayList<>();

        for (Proto.Event e : source) {
            events.add(decodeEvent0(e));
        }

        return events;
    }

    public ByteBuf encode0(Object msg) throws IOException {
        return encodeAll0(ImmutableList.of(msg));
    }

    public ByteBuf encodeAll0(Collection<Object> messages) throws IOException {
        final Proto.Msg.Builder builder = Proto.Msg.newBuilder();

        for (final Object d : messages) {
            if (d instanceof Metric) {
                builder.addEvents(encodeMetric0((Metric) d));
            } else if (d instanceof Event) {
                builder.addEvents(encodeEvent0((Event) d));
            }
        }

        final Proto.Msg m = builder.build();

        final ByteBuf work = Unpooled.buffer();

        try (final ByteBufOutputStream output = new ByteBufOutputStream(work)) {
            m.writeTo(output);

            final ByteBuf result = Unpooled.buffer();

            result.writeInt(work.writerIndex());
            result.writeBytes(work);

            return result;
        } finally {
            work.release();
        }
    }

    private Proto.Event.Builder encodeMetric0(final Metric d) {
        final Proto.Event.Builder b = Proto.Event.newBuilder();

        if (d.getKey() != null) {
            b.setService(d.getKey());
        }

        final String host = d.getTags().get("host");
        if (host != null) {
            b.setHost(host);
        }

        b.setMetricD(d.getValue());
        b.addAllAttributes(convertTags0(d.getTags()));

        b.addAllTags(d.getRiemannTags());
        b.setTime(toRiemannTime(d.getTime()));

        return b;
    }

    private Proto.Event.Builder encodeEvent0(final Event d) {
        final Proto.Event.Builder b = Proto.Event.newBuilder();
        if (d.getKey() != null) {
            b.setService(d.getKey());
        }

        if (d.getHost() != null) {
            b.setHost(d.getHost());
        }

        b.setMetricD(d.getValue());
        b.addAllAttributes(convertTags0(d.getTags()));

        b.addAllTags(d.getRiemannTags());
        b.setTime(toRiemannTime(d.getTime()));

        if (d.getDescription() != null) {
            b.setDescription(d.getDescription());
        }

        b.setTtl(d.getTtl());

        if (d.getState() != null) {
            b.setState(d.getState());
        }

        return b;
    }

    private Iterable<? extends Proto.Attribute> convertTags0(Map<String, String> tags) {
        final List<Proto.Attribute> attributes = new ArrayList<>();

        for (final Map.Entry<String, String> tag : tags.entrySet()) {
            attributes.add(Proto.Attribute.newBuilder().setKey(tag.getKey()).setValue(tag.getValue()).build());
        }

        return attributes;
    }

    private Map<String, String> convertTags0(List<Proto.Attribute> attributesList) {
        final Map<String, String> tags = new HashMap<>();

        for (final Proto.Attribute a : attributesList) {
            tags.put(a.getKey(), a.getValue());
        }

        return tags;
    }

    private double convertValue0(Proto.Event e) {
        if (e.hasMetricD()) {
            return e.getMetricD();
        }

        if (e.hasMetricSint64()) {
            return e.getMetricSint64();
        }

        if (e.hasMetricF()) {
            return e.getMetricF();
        }

        return Double.NaN;
    }

    private Object decodeEvent0(final Proto.Event event) {
        final String service = event.hasService() ? event.getService() : null;
        final Date time = event.hasTime() ? fromRiemannTime(event.getTime()) : null;
        final long ttl = (long) (event.hasTtl() ? event.getTtl() : 0f);
        final String state = event.hasState() ? event.getState() : null;
        final String description = event.hasDescription() ? event.getDescription() : null;
        final String host = event.hasHost() ? event.getHost() : null;
        final Set<String> riemannTags = new HashSet<>(event.getTagsList());
        final Map<String, String> tags = convertTags0(event.getAttributesList());

        final double value = convertValue0(event);

        return new Event(service, value, time, ttl, state, description, host, riemannTags, tags);
    }

    private Date fromRiemannTime(long time) {
        return new Date(time * 1000L);
    }

    private long toRiemannTime(Date d) {
        return d.getTime() / 1000L;
    }
}