// // typica - A client library for Amazon Web Services // Copyright (C) 2007,2008,2009 Xerox Corporation // // Licensed 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 com.xerox.amazonws.monitoring; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBException; import org.xml.sax.SAXException; import org.apache.http.HttpException; import org.apache.http.client.methods.HttpRequestBase; import org.apache.http.client.methods.HttpGet; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.xerox.amazonws.common.AWSException; import com.xerox.amazonws.common.AWSQueryConnection; import com.xerox.amazonws.typica.monitor.jaxb.Dimension; import com.xerox.amazonws.typica.monitor.jaxb.GetMetricStatisticsResponse; import com.xerox.amazonws.typica.monitor.jaxb.GetMetricStatisticsResult; import com.xerox.amazonws.typica.monitor.jaxb.ListMetricsResponse; import com.xerox.amazonws.typica.monitor.jaxb.ListMetricsResult; import com.xerox.amazonws.typica.monitor.jaxb.Metrics; /** * A Java wrapper for the Monitoring web services API */ public class Monitoring extends AWSQueryConnection { private static Log logger = LogFactory.getLog(Monitoring.class); private static String dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'"; /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. */ public Monitoring(String awsAccessId, String awsSecretKey) { this(awsAccessId, awsSecretKey, true); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. */ public Monitoring(String awsAccessId, String awsSecretKey, boolean isSecure) { this(awsAccessId, awsSecretKey, isSecure, "monitoring.amazonaws.com"); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. * @param server Which host to connect to. Usually, this will be monitoring.amazonaws.com */ public Monitoring(String awsAccessId, String awsSecretKey, boolean isSecure, String server) { this(awsAccessId, awsSecretKey, isSecure, server, isSecure ? 443 : 80); } /** * Initializes the ec2 service with your AWS login information. * * @param awsAccessId The your user key into AWS * @param awsSecretKey The secret string used to generate signatures for authentication. * @param isSecure True if the data should be encrypted on the wire on the way to or from EC2. * @param server Which host to connect to. Usually, this will be ec2.amazonaws.com * @param port Which port to use. */ public Monitoring(String awsAccessId, String awsSecretKey, boolean isSecure, String server, int port) { super(awsAccessId, awsSecretKey, isSecure, server, port); ArrayList<String> vals = new ArrayList<String>(); vals.add("2009-05-15"); super.headers.put("Version", vals); } /** * Describe the AMIs that match the intersection of the criteria supplied * * @param period granularity in seconds for the returned data points * @param namespace * @param statistics * @param dimensions one or more dimension along which to aggregate the data * @param startTime timestamp of the first datapoint * @param endTime timestamp of the last datapoint * @param measureName name of a measure for the gathered metric * @param unit standard unit of measurement for a given measure * @param customUnit user defined custom unit applied to a measure * @return A list of {@link Datapoint}. * @throws MonitoringException wraps checked exceptions */ public MetricStatisticsResult getMetricStatistics(int period, List<Statistics> statistics, String namespace, Map<String, String> dimensions, Date startTime, Date endTime, String measureName, StandardUnit unit, String customUnit) throws MonitoringException { Map<String, String> params = new HashMap<String, String>(); params.put("Period", ""+period); params.put("Namespace", namespace); SimpleDateFormat dateFormatter = new SimpleDateFormat(dateFormat); params.put("StartTime", dateFormatter.format(startTime)); params.put("EndTime", dateFormatter.format(endTime)); for (int i=0 ; i<statistics.size(); i++) { params.put("Statistics.member."+(i+1), statistics.get(i).getStatId()); } if (unit != null) { params.put("Unit", unit.getUnitId()); } if (customUnit != null && !customUnit.equals("")) { params.put("CustomUnit", customUnit); } if (dimensions != null && dimensions.size() > 0) { int i=0; for (String key : dimensions.keySet()) { String value = dimensions.get(key); params.put("Dimensions.member."+(i+1)+".Name", key); params.put("Dimensions.member."+(i+1)+".Value", value); i++; } } params.put("MeasureName", measureName); HttpGet method = new HttpGet(); GetMetricStatisticsResponse response = makeRequestInt(method, "GetMetricStatistics", params, GetMetricStatisticsResponse.class); GetMetricStatisticsResult result = response.getGetMetricStatisticsResult(); MetricStatisticsResult ret = new MetricStatisticsResult(result.getLabel()); List<Datapoint> dpList = ret.getDatapoints(); List<com.xerox.amazonws.typica.monitor.jaxb.Datapoint> dps = result.getDatapoints().getMembers(); for (com.xerox.amazonws.typica.monitor.jaxb.Datapoint dp : dps) { dpList.add(new Datapoint(dp.getTimestamp().toGregorianCalendar(), dp.getSamples(), dp.getAverage(), dp.getSum(), dp.getMinimum(), dp.getMaximum(), dp.getUnit(), dp.getCustomUnit())); } return ret; } /** * List the valid metrics that have recorded data available. * * @return A list of {@link Metric}. * @throws MonitoringException wraps checked exceptions */ public List<Metric> listMetrics() throws MonitoringException { Map<String, String> params = new HashMap<String, String>(); HttpGet method = new HttpGet(); List<Metric> ret = new ArrayList<Metric>(); String nextToken = null; do { if (nextToken != null) { params.put("NextToken", nextToken); } ListMetricsResponse response = makeRequestInt(method, "ListMetrics", params, ListMetricsResponse.class); ListMetricsResult result = response.getListMetricsResult(); Metrics mtrx = result.getMetrics(); for (com.xerox.amazonws.typica.monitor.jaxb.Metric m : mtrx.getMembers()) { Metric met = new Metric(m.getMeasureName(), m.getNamespace()); for (Dimension d : m.getDimensions().getMembers()) { met.addDimension(d.getName(), d.getValue()); } ret.add(met); } nextToken = result.getNextToken(); } while (nextToken != null); return ret; } protected <T> T makeRequestInt(HttpRequestBase method, String action, Map<String, String> params, Class<T> respType) throws MonitoringException { try { return makeRequest(method, action, params, respType); } catch (AWSException ex) { throw new MonitoringException(ex); } catch (JAXBException ex) { throw new MonitoringException("Problem parsing returned message.", ex); } catch (SAXException ex) { throw new MonitoringException("Problem parsing returned message.", ex); } catch (MalformedURLException ex) { throw new MonitoringException(ex.getMessage(), ex); } catch (IOException ex) { throw new MonitoringException(ex.getMessage(), ex); } catch (HttpException ex) { throw new MonitoringException(ex.getMessage(), ex); } } }