package com.sixsq.slipstream.connector;
import com.sixsq.slipstream.persistence.Vm;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
/**
*
* Set of static methods to start and end the recording of usage for a VM.
* Collaborates with clojure code, and is called by Collector.
*
*
* +=================================================================+
* 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.
* -=================================================================- *
*/
public class UsageRecorder {
private static Logger logger = Logger.getLogger(UsageRecorder.class.getName());
public static boolean isMuted = false;
private static Set<String> recordedVmInstanceIds = new HashSet<String>();
public static void muteForTests() {
isMuted = true;
logger.severe("You should NOT see this message in production: usage will *not* be recorded");
}
public static void insertStart(String instanceId, String user, String cloud, List<UsageMetric> metrics) {
try {
if(isMuted) {
return;
}
if(hasRecorded(cloud, instanceId)){
logger.fine("Already recorded => avoiding inserting usage record START for "
+ metrics + ", " + describe(instanceId, user, cloud));
return;
}
logger.fine("Inserting usage record START for " + metrics + ", " + describe(instanceId, user, cloud));
UsageEvent usageEvent = new UsageEvent(getAcl(user), user, cloud,
keyCloudVMInstanceID(cloud, instanceId), new Date(), null, metrics);
UsageEvent.post(usageEvent);
recordedVmInstanceIds.add(keyCloudVMInstanceID(cloud, instanceId));
logger.info("DONE Insert usage record START for " + describe(instanceId, user, cloud));
} catch (Exception e) {
logger.severe("Unable to insert usage record START:" + e.getMessage());
}
}
public static void insertEnd(String instanceId, String user, String cloud, List<UsageMetric> metrics) {
try {
if(isMuted) {
return;
}
logger.fine("Inserting usage record END, metrics" + metrics + ", for " + describe(instanceId, user, cloud));
UsageEvent usageEvent = new UsageEvent(getAcl(user), user, cloud,
keyCloudVMInstanceID(cloud, instanceId), null, new Date(), metrics);
UsageEvent.post(usageEvent);
recordedVmInstanceIds.remove(keyCloudVMInstanceID(cloud, instanceId));
logger.info("DONE Insert usage record END for " + describe(instanceId, user, cloud));
} catch (Exception e) {
logger.severe("Unable to insert usage record END:" + e.getMessage());
}
}
private static boolean hasRecorded(String cloud, String instanceId) {
logger.fine("UsageRecorder, recordedVmInstanceIds = " + recordedVmInstanceIds);
return recordedVmInstanceIds.contains(keyCloudVMInstanceID(cloud, instanceId));
}
private static ACL getAcl(String user) {
TypePrincipal owner = new TypePrincipal(TypePrincipal.PrincipalType.USER, user);
List<TypePrincipalRight> rules = Arrays.asList(
new TypePrincipalRight(TypePrincipal.PrincipalType.USER, user, TypePrincipalRight.Right.ALL),
new TypePrincipalRight(TypePrincipal.PrincipalType.ROLE, "ADMIN", TypePrincipalRight.Right.ALL));
return new ACL(owner, rules);
}
public static List<UsageMetric> createVmMetrics(Vm vm) {
List<UsageMetric> metrics = new ArrayList<UsageMetric>();
metrics.add(new UsageMetric("vm", "1.0"));
Integer cpu = vm.getCpu();
if (cpu != null) {
metrics.add(new UsageMetric(ConnectorBase.VM_CPU, cpu.toString()));
}
Float ram = vm.getRam();
if (ram != null) {
metrics.add(new UsageMetric(ConnectorBase.VM_RAM, ram.toString()));
}
Float disk = vm.getDisk();
if (disk != null) {
metrics.add(new UsageMetric(ConnectorBase.VM_DISK, disk.toString()));
}
String instanceType = vm.getInstanceType();
if (instanceType != null && !instanceType.isEmpty()) {
metrics.add(new UsageMetric("instance-type." + instanceType, "1.0"));
}
return metrics;
}
private static String keyCloudVMInstanceID(String cloud, String instanceId) {
return cloud + ":" + instanceId;
}
private static String describe(String instanceId, String user, String cloud) {
return "[" + user + ":" + cloud + "/" + instanceId + "]";
}
}