nebula.plugin.metrics.dispatcher.RestMetricsDispatcher.java Source code

Java tutorial

Introduction

Here is the source code for nebula.plugin.metrics.dispatcher.RestMetricsDispatcher.java

Source

/*
 *  Copyright 2015-2016 Netflix, Inc.
 *
 *  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 nebula.plugin.metrics.dispatcher;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import nebula.plugin.metrics.MetricsPluginExtension;
import org.apache.http.entity.ContentType;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.http.client.fluent.Request;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

public class RestMetricsDispatcher extends AbstractMetricsDispatcher {

    public RestMetricsDispatcher(MetricsPluginExtension extension) {
        super(extension, true);
        buildId = Optional.of(UUID.randomUUID().toString());
    }

    @Override
    protected String getLogCollectionName() {
        return extension.getRestLogEventName();
    }

    @Override
    protected String getBuildCollectionName() {
        return extension.getRestBuildEventName();
    }

    @Override
    protected String index(String indexName, String type, String source, Optional<String> id) {
        checkNotNull(indexName);
        checkNotNull(type);
        checkNotNull(source);
        checkNotNull(id);

        // id is ignored because the REST dispatcher generates one on startup.
        String payload = createPayloadJson(indexName, type, source, buildId.get());
        postPayload(payload);
        return buildId.get();
    }

    @Override
    protected void bulkIndex(String indexName, String type, Collection<String> sources) {
        checkNotNull(indexName);
        checkNotNull(type);
        checkState(sources.size() > 0);

        List<String> payloads = Lists.newArrayList();
        for (String source : sources) {
            payloads.add(createPayloadJson(indexName, type, source, buildId.get()));
        }

        postPayload(joinMultiplePayloads(payloads));
    }

    protected void postPayload(String payload) {
        checkNotNull(payload);

        try {
            Request postReq = Request.Post(extension.getRestUri());
            postReq.bodyString(payload, ContentType.APPLICATION_JSON);
            addHeaders(postReq);
            postReq.execute();
        } catch (IOException e) {
            throw new RuntimeException("Unable to POST to " + extension.getRestUri(), e);
        }
    }

    private String createPayloadJson(String indexName, String type, String payload, String buildId) {
        Map<String, String> payloadMap = Maps.newHashMap();
        payloadMap.put("buildId", buildId);
        payloadMap.put(type, payload);
        try {
            RestPayload sp = new RestPayload(indexName, payloadMap);
            return mapper.writeValueAsString(sp);
        } catch (JsonProcessingException e) {
            throw new RuntimeException("Unable to parse to payload", e);
        }
    }

    private String joinMultiplePayloads(Collection<String> payloads) {
        Joiner joiner = Joiner.on(", ").skipNulls();
        return String.format("[ %s ]", joiner.join(payloads));
    }

    @Override
    public Optional<String> receipt() {
        if (buildId.isPresent()) {
            return Optional.of(String.format("Metrics have been posted to %s (buildId: %s)", extension.getRestUri(),
                    buildId.get()));
        } else {
            return Optional.absent();
        }
    }

    protected void addHeaders(Request req) {
        checkNotNull(req);

        for (Map.Entry<String, String> entry : extension.getHeaders().entrySet()) {
            req.addHeader(entry.getKey(), entry.getValue());
        }
    }

    @VisibleForTesting
    public static class RestPayload {
        private String eventName;
        private Map<String, String> payload;

        public RestPayload() {
        }

        public RestPayload(String eventName, Map<String, String> payload) {
            this.eventName = eventName;
            this.payload = payload;
        }

        public String getEventName() {
            return eventName;
        }

        public Map<String, String> getPayload() {
            return payload;
        }

        public void setEventName(String eventName) {
            this.eventName = eventName;
        }

        public void setPayload(Map<String, String> payload) {
            this.payload = payload;
        }
    }

}