Package io.crate.udc.ping

Source Code of io.crate.udc.ping.PingTask

/*
* Licensed to CRATE Technology GmbH ("Crate") under one or more contributor
* license agreements.  See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.  Crate 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.
*
* However, if you have executed another commercial license agreement
* with Crate these terms will supersede the license and you may use the
* software solely pursuant to the terms of the relevant commercial agreement.
*/

package io.crate.udc.ping;

import com.google.common.base.Joiner;
import io.crate.ClusterIdService;
import io.crate.Version;
import org.elasticsearch.cluster.ClusterService;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.http.HttpServerTransport;
import org.hyperic.sigar.OperatingSystem;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class PingTask extends TimerTask {

    public static TimeValue HTTP_TIMEOUT = new TimeValue(5, TimeUnit.SECONDS);

    private ESLogger logger = Loggers.getLogger(this.getClass());

    private final ClusterService clusterService;
    private final ClusterIdService clusterIdService;
    private final HttpServerTransport httpServerTransport;
    private final String pingUrl;

    private AtomicLong successCounter = new AtomicLong(0);
    private AtomicLong failCounter = new AtomicLong(0);

    public PingTask(ClusterService clusterService,
                    ClusterIdService clusterIdService,
                    HttpServerTransport httpServerTransport,
                    String pingUrl) {
        this.clusterService = clusterService;
        this.clusterIdService = clusterIdService;
        this.httpServerTransport = httpServerTransport;
        this.pingUrl = pingUrl;
    }

    @SuppressWarnings("unchecked")
    public Map<String, Object> getKernelData() {
        return OperatingSystem.getInstance().toMap();
    }

    public @Nullable String getClusterId() {
        // wait until clusterId is available (master has been elected)
        try {
            return clusterIdService.clusterId().get().value().toString();
        } catch (InterruptedException|ExecutionException e) {
            if (logger.isTraceEnabled()) {
                logger.trace("Error getting cluster id", e);
            }
            return null;
        }
    }

    public Boolean isMasterNode() {
        return clusterService.localNode().isMasterNode();
    }

    public Map<String, Object> getCounters() {
        return new HashMap<String, Object>() {{
            put("success", successCounter.get());
            put("failure", failCounter.get());
        }};
    }

    public String getHardwareAddress() {
        TransportAddress transportAddress = httpServerTransport.boundAddress().publishAddress();
        if (!(transportAddress instanceof InetSocketTransportAddress)) {
            return null;
        }

        String hardwareAddress = null;
        InetAddress inetAddress = ((InetSocketTransportAddress) transportAddress).address().getAddress();
        try {
            NetworkInterface networkInterface = NetworkInterface.getByInetAddress(inetAddress);
            if (networkInterface != null) {
                if (networkInterface.getName().equals("lo")) {
                    hardwareAddress = "loopback device";
                } else {
                    byte[] hardwareAddressBytes = networkInterface.getHardwareAddress();
                    StringBuilder sb = new StringBuilder(18);
                    for (byte b : hardwareAddressBytes) {
                        if (sb.length() > 0)
                            sb.append(':');
                        sb.append(String.format("%02x", b));
                    }
                    hardwareAddress = sb.toString();
                }
            }

        } catch (SocketException e) {
            if (logger.isTraceEnabled()) {
                logger.trace("Error getting network interface", e);
            }
        }
        return hardwareAddress;
    }

    public String getCrateVersion() {
        return Version.CURRENT.number();
    }

    public String getJavaVersion() {
        return System.getProperty("java.version");
    }

    private URL buildPingUrl() throws URISyntaxException, IOException, NoSuchAlgorithmException {

        URI uri = new URI(this.pingUrl);

        Map<String, String> queryMap = new HashMap<>();
        queryMap.put("cluster_id", getClusterId()); // block until clusterId is available
        queryMap.put("kernel", XContentFactory.jsonBuilder().map(getKernelData()).string());
        queryMap.put("master", isMasterNode().toString());
        queryMap.put("ping_count", XContentFactory.jsonBuilder().map(getCounters()).string());
        queryMap.put("hardware_address", getHardwareAddress());
        queryMap.put("crate_version", getCrateVersion());
        queryMap.put("java_version", getJavaVersion());

        if (logger.isDebugEnabled()) {
            logger.debug("Sending data: {}", queryMap);
        }

        final Joiner joiner = Joiner.on('=');
        List<String> params = new ArrayList<>(queryMap.size());
        for (Map.Entry<String, String> entry : queryMap.entrySet()) {
            if (entry.getValue() != null) {
                params.add(joiner.join(entry.getKey(), entry.getValue()));
            }
        }
        String query = Joiner.on('&').join(params);

        return new URI(
                uri.getScheme(), uri.getUserInfo(), uri.getHost(), uri.getPort(),
                uri.getPath(), query, uri.getFragment()
        ).toURL();
    }

    @Override
    public void run() {
        try {
            URL url = buildPingUrl();
            if (logger.isDebugEnabled()) {
                logger.debug("Sending UDC information to {}...", url);
            }
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            conn.setConnectTimeout((int)HTTP_TIMEOUT.millis());
            conn.setReadTimeout((int)HTTP_TIMEOUT.millis());

            if (conn.getResponseCode() >= 300) {
                throw new Exception(String.format("%s Responded with Code %d", url.getHost(), conn.getResponseCode()));
            }
            if (logger.isDebugEnabled()) {
                BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                String line = reader.readLine();
                while (line != null) {
                    logger.debug(line);
                    line = reader.readLine();
                }
                reader.close();
            } else {
                conn.getInputStream().close();
            }
            successCounter.incrementAndGet();
        } catch (Exception e) {
            if (logger.isDebugEnabled()) {
                logger.debug("Error sending UDC information", e);
            }
            failCounter.incrementAndGet();
        }
    }
}
TOP

Related Classes of io.crate.udc.ping.PingTask

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.