/* * RHQ Management Platform * Copyright (C) 2005-2009 Red Hat, Inc. * All rights reserved. * * 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 version 2 of the License. * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.plugins.twitter; import java.net.URL; import java.net.MalformedURLException; import java.util.List; import java.util.Properties; import java.util.Set; import twitter4j.Paging; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterFactory; import twitter4j.auth.AuthorizationFactory; import twitter4j.conf.PropertyConfiguration; import org.rhq.core.domain.configuration.Configuration; import org.rhq.core.domain.measurement.AvailabilityType; import org.rhq.core.domain.measurement.MeasurementDataNumeric; import org.rhq.core.domain.measurement.MeasurementReport; import org.rhq.core.domain.measurement.MeasurementScheduleRequest; import org.rhq.core.pluginapi.event.EventContext; import org.rhq.core.pluginapi.inventory.ResourceComponent; import org.rhq.core.pluginapi.inventory.ResourceContext; import org.rhq.core.pluginapi.inventory.InvalidPluginConfigurationException; import org.rhq.core.pluginapi.measurement.MeasurementFacet; import org.rhq.core.pluginapi.operation.OperationFacet; import org.rhq.core.pluginapi.operation.OperationResult; /** * Implementation of the Twitter subsystem functionality. * Most work is done in the children. This component allows * to post tweets and to monitor the users timeline when username * and password are given. * * @author Heiko W. Rupp */ public class TwitterComponent implements ResourceComponent<ResourceComponent<?>>, OperationFacet, MeasurementFacet { private static final String TWIT_EVENT = "TwitterEvent"; private static final int NOT_YET_SET = -1; EventContext eventContext; private String username; private String password; private String serverUrl; private String searchBaseUrl; private TwitterFactory tFactory; private TwitterEventPoller eventPoller; private long lastId = NOT_YET_SET; private static final String HTTP_TWITTER_COM = "http://twitter.com/"; /** * Return availability of this resource * @see org.rhq.core.pluginapi.inventory.ResourceComponent#getAvailability() */ public AvailabilityType getAvailability() { return AvailabilityType.UP; } /** * Start the resource connection * @see org.rhq.core.pluginapi.inventory.ResourceComponent#start(org.rhq.core.pluginapi.inventory.ResourceContext) */ public void start(ResourceContext context) throws Exception { Configuration conf = context.getPluginConfiguration(); username = conf.getSimpleValue("user",null); password = conf.getSimpleValue("password",null); String url = conf.getSimpleValue("baseurl", HTTP_TWITTER_COM); if (!url.endsWith("/")) url= url+"/"; try { new URL(url); serverUrl = url; } catch (MalformedURLException e) { throw new InvalidPluginConfigurationException(e.getMessage()); } url = conf.getSimpleValue("searchBaseUrl", "http://search.twitter.com/"); if (!url.endsWith("/")) url= url+"/"; try { new URL(url); searchBaseUrl = url; } catch (MalformedURLException e) { throw new InvalidPluginConfigurationException(e.getMessage()); } eventContext = context.getEventContext(); eventPoller = new TwitterEventPoller(TWIT_EVENT); eventContext.registerEventPoller(eventPoller, 53); Properties props = new Properties(); //props.put(PropertyConfiguration.SOURCE,"Jopr"); props.put(PropertyConfiguration.HTTP_USER_AGENT,"Jopr"); props.put(PropertyConfiguration.SEARCH_BASE_URL,searchBaseUrl); props.put(PropertyConfiguration.REST_BASE_URL,serverUrl); twitter4j.conf.Configuration tconf = new PropertyConfiguration(props); tFactory = new TwitterFactory(tconf); } /** * Tear down the rescource connection * @see org.rhq.core.pluginapi.inventory.ResourceComponent#stop() */ public void stop() { eventContext.unregisterEventPoller(TWIT_EVENT); } /** * Gather measurement data * @see org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues(org.rhq.core.domain.measurement.MeasurementReport, java.util.Set) */ public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception { Twitter twitter = createTwitterInstance(); for (MeasurementScheduleRequest req : metrics) { if (req.getName().equals("tweetCount")) { // Twitter twitter = new Twitter(username,password,serverUrl); Paging paging = new Paging(); if (lastId == NOT_YET_SET) { paging.setSinceId(1); paging.setCount(1); } else { paging.setSinceId(lastId); paging.setCount(100); } List<Status> statuses; statuses = twitter.getHomeTimeline(paging); if (lastId>0) { MeasurementDataNumeric res; res = new MeasurementDataNumeric(req, (double) statuses.size()); eventPoller.addStatuses(statuses); report.addData(res); } if (statuses.size()>0) lastId = statuses.get(0).getId(); // This is always newest first } else if (req.getName().equals("followerCount")) { int count = twitter.getFollowersIDs(-1).getIDs().length; MeasurementDataNumeric res; res = new MeasurementDataNumeric(req,(double)count); report.addData(res); } } } private Twitter createTwitterInstance() { Properties props = new Properties(); props.setProperty(PropertyConfiguration.USER, username); props.setProperty(PropertyConfiguration.PASSWORD, password); PropertyConfiguration propConfig = new PropertyConfiguration(props); return tFactory.getInstance(AuthorizationFactory.getInstance(propConfig)); } /** * Implementation of the OperationFacet * Sends a tweet * @param name the name of the operation * @param configuration parameters of the operation * @return result of the operation * @throws Exception If anything goes wrong */ public OperationResult invokeOperation(String name, Configuration configuration) throws Exception { if (name!=null && name.equals("postStatus")) { if (username==null || password==null) { throw new IllegalArgumentException("User or password were not set"); } String message = configuration.getSimpleValue("message",null); Twitter twitter = createTwitterInstance(); Status status = twitter.updateStatus(message); @SuppressWarnings({"UnnecessaryLocalVariable"}) OperationResult result = new OperationResult("Posted " + status.getText()); return result; } throw new UnsupportedOperationException("Operation " + name + " is not valid"); } protected String getServerUrl() { return serverUrl; } protected String getSearchUrl() { return searchBaseUrl; } }