package com.sixsq.slipstream.metering;
/*
* +=================================================================+
* SlipStream Server (WAR)
* =====
* Copyright (C) 2013 SixSq Sarl (sixsq.com)
* =====
* 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.
* -=================================================================-
*/
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.List;
import com.sixsq.slipstream.connector.Connector;
import com.sixsq.slipstream.connector.ConnectorFactory;
import com.sixsq.slipstream.exceptions.AbortException;
import com.sixsq.slipstream.exceptions.ConfigurationException;
import com.sixsq.slipstream.exceptions.NotFoundException;
import com.sixsq.slipstream.exceptions.ValidationException;
import com.sixsq.slipstream.persistence.CloudUsage;
import com.sixsq.slipstream.persistence.User;
import com.sixsq.slipstream.persistence.Vm;
import com.sixsq.slipstream.util.Logger;
public class Metering {
@SuppressWarnings("unused")
public static String populate(User user)
throws ConfigurationException, ValidationException, NotFoundException, AbortException {
return populate(user.getName());
}
public static String populate(String user)
throws ConfigurationException, ValidationException, NotFoundException, AbortException {
Map<String, Integer> usageData = produceCloudUsageData(user);
String data = transformUsageDataForGraphite(user, usageData);
sendToGraphite(data);
return data;
}
@SuppressWarnings("unused")
public static String populate(User user, Connector connector)
throws ConfigurationException, ValidationException, NotFoundException, AbortException {
return populate(user.getName(), connector);
}
public static String populate(String user, Connector connector)
throws ConfigurationException, ValidationException, NotFoundException, AbortException {
List<String> cloudServiceNamesList = new ArrayList<String>();
cloudServiceNamesList.add(connector.getConnectorInstanceName());
Map<String, Integer> usageData = produceCloudUsageData(user, cloudServiceNamesList);
String data = transformUsageDataForGraphite(user, usageData);
sendToGraphite(data);
return data;
}
public static void populateVmMetrics(String user, String cloud, int cpu, float ram, float disk, Map<String, Integer> instanceTypes) {
String data = "";
data += generateGraphiteData(user, cloud, "cpu-nb", cpu);
data += generateGraphiteData(user, cloud, "ram-mb", ram);
data += generateGraphiteData(user, cloud, "disk-gb", disk);
for (Map.Entry<String, Integer> instanceType: instanceTypes.entrySet()) {
data += generateGraphiteData(user, cloud, "instance-type." + instanceType.getKey(), instanceType.getValue());
}
sendToGraphite(data);
}
public static Map<String, Integer> produceCloudUsageData(String user)
throws ConfigurationException, ValidationException {
return produceCloudUsageData(user, ConnectorFactory.getCloudServiceNamesList());
}
public static Map<String, Integer> produceCloudUsageData(String user, List<String> cloudServiceNamesList)
throws ConfigurationException, ValidationException {
Map<String, Integer> cloudUsage = new HashMap<String, Integer>();
Map<String, CloudUsage> vmUsage = Vm.usage(user);
for (String cloud : cloudServiceNamesList) {
Integer currentUsage = 0;
if (vmUsage.containsKey(cloud)) {
currentUsage += vmUsage.get(cloud).getUserVmUsage();
}
cloudUsage.put(cloud, currentUsage);
}
return cloudUsage;
}
public static String sendToGraphite(String data) {
String errorMessageBase = "Measurements. Failed to send usage data to Graphite.";
try {
Socket conn = new Socket("localhost", 2003);
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(data);
conn.close();
} catch (UnknownHostException e) {
Logger.severe(errorMessageBase + " 'Unknown host' : " + e.getMessage());
} catch (IOException e) {
Logger.severe(errorMessageBase + " 'IO exception' : " + e.getMessage());
}
return data;
}
private static String generateUsageMetricName(String user, String cloud, String name) {
return "slipstream." + user + ".usage." + name + "." + cloud;
}
private static String generateGraphiteData(String user, String cloud, String name, float value) {
int timestamp = (int) (System.currentTimeMillis() / 1000L);
return generateUsageMetricName(user, cloud, name) + " " + String.valueOf(value) + " " + String.valueOf(timestamp) + "\n";
}
public static String transformUsageDataForGraphite(String user, Map<String, Integer> usages) {
String buffer = "";
for (Map.Entry<String, Integer> usage : usages.entrySet()) {
String cloud = usage.getKey();
buffer += generateGraphiteData(user, cloud, "instance", usage.getValue());
}
return buffer;
}
}