org.wattdepot.client.http.api.collector.MultiThreadedCollector.java Source code

Java tutorial

Introduction

Here is the source code for org.wattdepot.client.http.api.collector.MultiThreadedCollector.java

Source

/**
 * MultiThreadedCollector.java This file is part of WattDepot.
 *
 * Copyright (C) 2013  Cam Moore
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.wattdepot.client.http.api.collector;

import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.validator.routines.UrlValidator;
import org.wattdepot.client.http.api.WattDepotClient;
import org.wattdepot.common.domainmodel.CollectorProcessDefinition;
import org.wattdepot.common.domainmodel.Depository;
import org.wattdepot.common.domainmodel.Sensor;
import org.wattdepot.common.domainmodel.SensorModel;
import org.wattdepot.common.exception.BadCredentialException;
import org.wattdepot.common.exception.BadSensorUriException;
import org.wattdepot.common.exception.IdNotFoundException;
import org.wattdepot.common.util.SensorModelHelper;
import org.wattdepot.common.util.Slug;
import org.wattdepot.common.util.tstamp.Tstamp;

/**
 * MultiThreadedCollector - Abstract base class for all Multi-Threaded
 * Collectors.
 * 
 * @author Cam Moore
 * 
 */
public abstract class MultiThreadedCollector extends TimerTask {

    /** Flag for debugging messages. */
    protected boolean debug;
    /** The definition about the collector. */
    protected CollectorProcessDefinition definition;

    /** The client used to communicate with the WattDepot server. */
    protected WattDepotClient client;
    /** The Depository for storing measurements. */
    protected Depository depository;

    /**
     * Initializes the MultiThreadedCollector.
     * 
     * @param serverUri The URI for the WattDepot server.
     * @param username The name of a user defined in the WattDepot server.
     * @param orgId the id of the organization the user is in.
     * @param password The password for the user.
     * @param collectorId The CollectorProcessDefinitionId used to initialize this
     *        collector.
     * @param debug flag for debugging messages.
     * @throws BadCredentialException if the user or password don't match the
     *         credentials in WattDepot.
     * @throws IdNotFoundException if the processId is not defined.
     * @throws BadSensorUriException if the Sensor's URI isn't valid.
     */
    public MultiThreadedCollector(String serverUri, String username, String orgId, String password,
            String collectorId, boolean debug)
            throws BadCredentialException, IdNotFoundException, BadSensorUriException {
        this.client = new WattDepotClient(serverUri, username, orgId, password);
        this.debug = debug;
        this.definition = client.getCollectorProcessDefinition(collectorId);
        this.depository = client.getDepository(definition.getDepositoryId());
        validate();
    }

    /**
     * @param serverUri The URI for the WattDepot server.
     * @param username The name of a user defined in the WattDepot server.
     * @param orgId the id of the user's organization.
     * @param password The password for the user.
     * @param sensorId The id of the Sensor to poll.
     * @param pollingInterval The polling interval in seconds.
     * @param depository The Depository to store the measurements.
     * @param debug flag for debugging messages.
     * @throws BadCredentialException if the user or password don't match the
     *         credentials in WattDepot.
     * @throws BadSensorUriException if the Sensor's URI isn't valid.
     * @throws IdNotFoundException if there is a problem with the sensorId.
     */
    public MultiThreadedCollector(String serverUri, String username, String orgId, String password, String sensorId,
            Long pollingInterval, Depository depository, boolean debug)
            throws BadCredentialException, BadSensorUriException, IdNotFoundException {
        this.client = new WattDepotClient(serverUri, username, orgId, password);
        this.debug = debug;
        this.definition = new CollectorProcessDefinition(
                Slug.slugify(sensorId + " " + pollingInterval + " " + depository.getName()), sensorId,
                pollingInterval, depository.getName(), null);
        client.putCollectorProcessDefinition(definition);
        this.depository = depository;
        client.putDepository(depository);
        validate();
    }

    /**
     * @return true if everything is good to go.
     */
    public boolean isValid() {
        if (this.client != null && this.definition != null) {
            return true;
        }
        return false;
    }

    /**
     * @param serverUri The URI for the WattDepot server.
     * @param username The name of a user defined in the WattDepot server.
     * @param orgId the user's organization id.
     * @param password The password for the user.
     * @param collectorId The CollectorProcessDefinitionId used to initialize this
     *        collector.
     * @param debug flag for debugging messages.
     * @return true if sensor starts successfully.
     * @throws InterruptedException If sleep is interrupted for some reason.
     * @throws BadCredentialException if the username and password are invalid.
     */
    public static boolean start(String serverUri, String username, String orgId, String password,
            String collectorId, boolean debug) throws InterruptedException, BadCredentialException {

        // Before starting any sensors, confirm that we can connect to the WattDepot
        // server. We do
        // this here because if the server and sensors are running on the same
        // system, at boot time the
        // sensor might start before the server, causing client calls to fail. If
        // this happens, we
        // want to catch it at the top level, where it will result in the sensor
        // process terminating.
        // If we wait to catch it at the per-sensor level, it might cause a sensor
        // to abort for what
        // might be a short-lived problem. The sensor process should be managed by
        // some other process
        // (such as launchd), so it is OK to terminate because it should get
        // restarted if the server
        // isn't up quite yet.
        WattDepotClient staticClient = new WattDepotClient(serverUri, username, orgId, password);
        if (!staticClient.isHealthy()) {
            System.err.format("Could not connect to server %s. Aborting.%n", serverUri);
            // Pause briefly to rate limit restarts if server doesn't come up for a
            // long time
            Thread.sleep(2000);
            return false;
        }
        // Get the collector process definition
        CollectorProcessDefinition definition = null;
        Sensor sensor = null;
        SensorModel model = null;

        try {
            definition = staticClient.getCollectorProcessDefinition(collectorId);
            staticClient.getDepository(definition.getDepositoryId());
            sensor = staticClient.getSensor(definition.getSensorId());
            model = staticClient.getSensorModel(sensor.getModelId());
            // Get SensorModel to determine what type of collector to start.
            if (model.getName().equals(SensorModelHelper.EGAUGE) && model.getVersion().equals("1.0")) {
                Timer t = new Timer();
                try {
                    EGaugeCollector collector = new EGaugeCollector(serverUri, username, sensor.getOrganizationId(),
                            password, collectorId, debug);
                    if (collector.isValid()) {
                        System.out.format("Started polling %s sensor at %s%n", sensor.getName(),
                                Tstamp.makeTimestamp());
                        t.schedule(collector, 0, definition.getPollingInterval() * 1000);
                    } else {
                        System.err.format("Cannot poll %s sensor%n", sensor.getName());
                        return false;
                    }
                } catch (BadSensorUriException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IdNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (model.getName().equals(SensorModelHelper.SHARK) && model.getVersion().equals("1.03")) {
                Timer t = new Timer();
                try {
                    SharkCollector collector = new SharkCollector(serverUri, username, orgId, password, collectorId,
                            debug);
                    if (collector.isValid()) {
                        System.out.format("Started polling %s sensor at %s%n", sensor.getName(),
                                Tstamp.makeTimestamp());
                        t.schedule(collector, 0, definition.getPollingInterval() * 1000);
                    } else {
                        System.err.format("Cannot poll %s sensor%n", sensor.getName());
                        return false;
                    }
                } catch (IdNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (BadSensorUriException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (model.getName().equals(SensorModelHelper.STRESS)) {
                Timer t = new Timer();
                try {
                    StressCollector collector = new StressCollector(serverUri, username, orgId, password,
                            collectorId, debug);
                    if (collector.isValid()) {
                        System.out.format("Started polling %s sensor at %s%n", sensor.getName(),
                                Tstamp.makeTimestamp());
                        t.schedule(collector, 0, definition.getPollingInterval() * 1000);
                    } else {
                        System.err.format("Cannot poll %s sensor%n", sensor.getName());
                        return false;
                    }
                } catch (IdNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (BadSensorUriException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } else if (model.getName().equals(SensorModelHelper.WEATHER)) {
                Timer t = new Timer();
                try {
                    NOAAWeatherCollector collector = new NOAAWeatherCollector(serverUri, username, orgId, password,
                            collectorId, debug);
                    if (collector.isValid()) {
                        System.out.format("Started polling %s sensor at %s%n", sensor.getName(),
                                Tstamp.makeTimestamp());
                        t.schedule(collector, 0, definition.getPollingInterval() * 1000);
                    } else {
                        System.err.format("Cannot poll %s sensor%n", sensor.getName());
                        return false;
                    }
                } catch (IdNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (BadSensorUriException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        } catch (IdNotFoundException e) {
            System.err.println(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * @throws BadSensorUriException if the Sensor's URI isn't valid.
     * @throws IdNotFoundException if there is a problem with the Collector
     *         Process Definition.
     */
    private void validate() throws BadSensorUriException, IdNotFoundException {
        Sensor s = client.getSensor(definition.getSensorId());
        String[] schemes = { "http", "https" };
        UrlValidator urlValidator = new UrlValidator(schemes);
        if (!urlValidator.isValid(s.getUri())) {
            throw new BadSensorUriException(s.getUri() + " is not a valid URI.");
        }
    }
}