org.hornetq.integration.twitter.impl.OutgoingTweetsHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.hornetq.integration.twitter.impl.OutgoingTweetsHandler.java

Source

/*
 * Copyright 2005-2014 Red Hat, Inc.
 * Red Hat 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.
 */
package org.hornetq.integration.twitter.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import org.hornetq.api.core.SimpleString;
import org.hornetq.core.filter.Filter;
import org.hornetq.core.postoffice.Binding;
import org.hornetq.core.postoffice.PostOffice;
import org.hornetq.core.server.ConnectorService;
import org.hornetq.core.server.Consumer;
import org.hornetq.core.server.HandleStatus;
import org.hornetq.core.server.HornetQServerLogger;
import org.hornetq.core.server.MessageReference;
import org.hornetq.core.server.Queue;
import org.hornetq.core.server.ServerMessage;
import org.hornetq.integration.twitter.TwitterConstants;
import org.hornetq.twitter.HornetQTwitterLogger;
import org.hornetq.utils.ConfigurationHelper;
import twitter4j.GeoLocation;
import twitter4j.StatusUpdate;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.http.AccessToken;

/**
 * OutgoingTweetsHandler consumes from configured HornetQ address
 * and forwards to the twitter.
 */
public class OutgoingTweetsHandler implements Consumer, ConnectorService {
    private final String connectorName;

    private final String consumerKey;

    private final String consumerSecret;

    private final String accessToken;

    private final String accessTokenSecret;

    private final String queueName;

    private final PostOffice postOffice;

    private Twitter twitter = null;

    private Queue queue = null;

    private Filter filter = null;

    private boolean isStarted = false;

    public String debug() {
        return toString();
    }

    public OutgoingTweetsHandler(final String connectorName, final Map<String, Object> configuration,
            final PostOffice postOffice) {
        this.connectorName = connectorName;
        this.consumerKey = ConfigurationHelper.getStringProperty(TwitterConstants.CONSUMER_KEY, null,
                configuration);
        this.consumerSecret = ConfigurationHelper.getStringProperty(TwitterConstants.CONSUMER_SECRET, null,
                configuration);
        this.accessToken = ConfigurationHelper.getStringProperty(TwitterConstants.ACCESS_TOKEN, null,
                configuration);
        this.accessTokenSecret = ConfigurationHelper.getStringProperty(TwitterConstants.ACCESS_TOKEN_SECRET, null,
                configuration);
        this.queueName = ConfigurationHelper.getStringProperty(TwitterConstants.QUEUE_NAME, null, configuration);
        this.postOffice = postOffice;
    }

    /**
     * TODO streaming API support
     * TODO rate limit support
     */
    public synchronized void start() throws Exception {
        if (this.isStarted) {
            return;
        }

        if (this.connectorName == null || this.connectorName.trim().equals("")) {
            throw new Exception("invalid connector name: " + this.connectorName);
        }

        if (this.queueName == null || this.queueName.trim().equals("")) {
            throw new Exception("invalid queue name: " + queueName);
        }

        SimpleString name = new SimpleString(this.queueName);
        Binding b = this.postOffice.getBinding(name);
        if (b == null) {
            throw new Exception(connectorName + ": queue " + queueName + " not found");
        }
        this.queue = (Queue) b.getBindable();

        TwitterFactory tf = new TwitterFactory();
        this.twitter = tf.getOAuthAuthorizedInstance(this.consumerKey, this.consumerSecret,
                new AccessToken(this.accessToken, this.accessTokenSecret));
        this.twitter.verifyCredentials();

        // TODO make filter-string configurable
        // this.filter = FilterImpl.createFilter(filterString);
        this.filter = null;

        this.queue.addConsumer(this);

        this.queue.deliverAsync();
        this.isStarted = true;
        HornetQTwitterLogger.LOGGER.debug(connectorName + ": started");
    }

    public boolean isStarted() {
        return isStarted; //To change body of implemented methods use File | Settings | File Templates.
    }

    public synchronized void stop() throws Exception {
        if (!this.isStarted) {
            return;
        }

        HornetQTwitterLogger.LOGGER.debug(connectorName + ": receive shutdown request");

        this.queue.removeConsumer(this);

        this.isStarted = false;
        HornetQTwitterLogger.LOGGER.debug(connectorName + ": shutdown");
    }

    public String getName() {
        return connectorName;
    }

    public Filter getFilter() {
        return filter;
    }

    /* (non-Javadoc)
     * @see org.hornetq.core.server.Consumer#getDeliveringMessages()
     */
    @Override
    public List<MessageReference> getDeliveringMessages() {
        return Collections.emptyList();
    }

    public HandleStatus handle(final MessageReference ref) throws Exception {
        if (filter != null && !filter.match(ref.getMessage())) {
            return HandleStatus.NO_MATCH;
        }

        synchronized (this) {
            ref.handled();

            ServerMessage message = ref.getMessage();

            StatusUpdate status = new StatusUpdate(message.getBodyBuffer().readString());

            // set optional property

            if (message.containsProperty(TwitterConstants.KEY_IN_REPLY_TO_STATUS_ID)) {
                status.setInReplyToStatusId(message.getLongProperty(TwitterConstants.KEY_IN_REPLY_TO_STATUS_ID));
            }

            if (message.containsProperty(TwitterConstants.KEY_GEO_LOCATION_LATITUDE)) {
                double geolat = message.getDoubleProperty(TwitterConstants.KEY_GEO_LOCATION_LATITUDE);
                double geolong = message.getDoubleProperty(TwitterConstants.KEY_GEO_LOCATION_LONGITUDE);
                status.setLocation(new GeoLocation(geolat, geolong));
            }

            if (message.containsProperty(TwitterConstants.KEY_PLACE_ID)) {
                status.setPlaceId(message.getStringProperty(TwitterConstants.KEY_PLACE_ID));
            }

            if (message.containsProperty(TwitterConstants.KEY_DISPLAY_COODINATES)) {
                status.setDisplayCoordinates(message.getBooleanProperty(TwitterConstants.KEY_DISPLAY_COODINATES));
            }

            // send to Twitter
            try {
                this.twitter.updateStatus(status);
            } catch (TwitterException e) {
                if (e.getStatusCode() == 403) {
                    // duplicated message
                    HornetQTwitterLogger.LOGGER.error403(connectorName);
                    queue.acknowledge(ref);

                    return HandleStatus.HANDLED;
                } else {
                    throw e;
                }
            }

            queue.acknowledge(ref);
            HornetQTwitterLogger.LOGGER.debug(connectorName + ": forwarded to twitter: " + message.getMessageID());
            return HandleStatus.HANDLED;
        }
    }

    public void proceedDeliver(MessageReference ref) {
        // no op
    }

    @Override
    public String toManagementString() {
        return toString();
    }

    @Override
    public void disconnect() {
        try {
            stop();
        } catch (Exception e) {
            HornetQServerLogger.LOGGER.errorStoppingConnectorService(e, getName());
        }
    }
}