/* * RHQ Management Platform * Copyright (C) 2005-2012 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.enterprise.server.plugins.alertSms; import java.io.BufferedReader; import java.io.StringReader; import java.net.URI; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.Locale; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; import org.apache.commons.httpclient.Credentials; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.UsernamePasswordCredentials; import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jboss.resteasy.client.ClientExecutor; import org.jboss.resteasy.client.ClientRequest; import org.jboss.resteasy.client.ClientRequestFactory; import org.jboss.resteasy.client.ClientResponse; import org.jboss.resteasy.client.core.executors.ApacheHttpClientExecutor; import org.rhq.core.domain.alert.Alert; import org.rhq.core.domain.alert.notification.SenderResult; import org.rhq.core.domain.configuration.PropertySimple; import org.rhq.core.domain.resource.Resource; import org.rhq.enterprise.server.configuration.ConfigurationManagerLocal; import org.rhq.enterprise.server.plugin.pc.alert.AlertSender; import org.rhq.enterprise.server.util.LookupUtil; /** * Sender class for Alerts * @author Heiko W. Rupp */ public class SmsSender extends AlertSender { private final Log log = LogFactory.getLog(SmsSender.class); private static final String DEVGARDEN_SMS_GW = "https://gateway.developer.telekom.com/p3gw-mod-odg-sms/rest"; private static final String DEVGARDEN_SECURE_TOKEN_SERVER = "https://sts.idm.telekom.com/rest-v1/tokens/odg"; private static final String TOKEN_EXPIRY_TIME = "token-expiry-time"; private static final String TOKEN = "token"; @Override public SenderResult send(Alert alert) { String token; try { token = getToken(); } catch (Exception e) { SenderResult senderResult = new SenderResult(); senderResult.addFailureMessage("Can not obtain token: " + e.getMessage()); return senderResult; } Resource res = alert.getAlertDefinition().getResource(); Integer alertId = alert.getId(); StringBuilder b = new StringBuilder(); b.append("Alert "); b.append("(").append(alertId).append("): "); b.append(res.getName()); b.append(",id=(").append(res.getId()).append(")"); b.append("Brought by RHQ"); try { sendAlertSms(token,b.toString()); } catch (Exception e) { SenderResult senderResult = new SenderResult(); senderResult.addFailureMessage("Failed to send SMS: " + e.getMessage()); return senderResult; } SenderResult senderResult = new SenderResult(); String tel = alertParameters.getSimpleValue("tel",null); senderResult.addSuccessMessage("SMS to " + tel + " sent"); return senderResult; } /** * Do the actual SMS sending. For this to succeed, it needs an auth token. * @param token valid access token * @param message the message to send */ private void sendAlertSms(String token, String message) throws Exception { String mode = preferences.getSimpleValue("environment","sandbox"); String tel = alertParameters.getSimpleValue("tel",null); if (tel==null) throw new IllegalArgumentException("No telephone number given"); ClientRequest req = new ClientRequest(DEVGARDEN_SMS_GW + "/" + mode + "/sms"); String body = "number=" + tel + "&" + "message=" + message; // TODO encode? req.body(MediaType.APPLICATION_FORM_URLENCODED, body); req.header("Authorization","TAuth realm=\"https://odg.t-online.de\",tauth_token=\"" + token + "\""); req.accept(MediaType.TEXT_PLAIN_TYPE); try { ClientResponse resp = req.post(String.class); if (resp.getStatus()==200) { log.debug(resp.getEntity()); } else { log.warn("Error while sending SMS " + resp.getStatus()); log.debug(resp.getEntity()); throw new RuntimeException((String) resp.getEntity()); } } catch (Exception e) { throw (e); } } /** * Get a token from the secure token server if needed. Store the token * in preferences for caching purposes. * @return a token if everything is ok * @throws Exception if no token can be obtained. */ private String getToken() throws Exception { String token = preferences.getSimpleValue(TOKEN,null); PropertySimple tokenTimeProp = preferences.getSimple(TOKEN_EXPIRY_TIME); Long tokenExpTime = null; if (tokenTimeProp!=null) tokenExpTime = tokenTimeProp.getLongValue(); long TWO_MINUTES = 1000L * 60L * 2L; if (token == null || tokenExpTime == null || tokenExpTime < System.currentTimeMillis() + TWO_MINUTES) { String userId = preferences.getSimpleValue("login",null); String password = preferences.getSimpleValue("password",null); if (userId==null || password==null) throw new IllegalArgumentException("User name or password were missing"); Credentials credentials = new UsernamePasswordCredentials(userId, password); HttpClient httpClient = new HttpClient(); httpClient.getState().setCredentials(AuthScope.ANY, credentials); httpClient.getParams().setAuthenticationPreemptive(true); ClientExecutor clientExecutor = new ApacheHttpClientExecutor(httpClient); try { URI uri = new URI(DEVGARDEN_SECURE_TOKEN_SERVER); ClientRequestFactory fac = new ClientRequestFactory(clientExecutor,uri); ClientRequest request = fac.createRequest(DEVGARDEN_SECURE_TOKEN_SERVER); request.accept(MediaType.TEXT_PLAIN_TYPE); ClientResponse resp = request.get(String.class); // TODO check status log.debug(resp.getStatus()); String response = (String) resp.getEntity(); BufferedReader reader = new BufferedReader(new StringReader(response)); while (reader.ready()) { String line = reader.readLine(); if (line.startsWith("token=")) { token = line.substring(6); break; } } log.debug("Token: " + token); MultivaluedMap<String, List> headers = resp.getHeaders(); List expiresList = headers.get("Expires"); String expires = (String) expiresList.get(0); SimpleDateFormat df = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z", Locale.US); Date date = df.parse(expires); if (tokenTimeProp==null) { tokenTimeProp=new PropertySimple(TOKEN_EXPIRY_TIME, date.getTime()); preferences.put(tokenTimeProp); } else tokenTimeProp.setLongValue(date.getTime()); PropertySimple tokenProp = preferences.getSimple(TOKEN); if (tokenProp ==null) { tokenProp = new PropertySimple(TOKEN,token); preferences.put(tokenProp); } else { tokenProp.setStringValue(token); } ConfigurationManagerLocal mgr = LookupUtil.getConfigurationManager(); mgr.mergeConfiguration(preferences); } catch (Exception e) { log.error("Error while retrieving a token: " + e.getMessage()); throw e; } } return token; } }