package com.intuit.tank.vmManager;
/*
* #%L
* VmManager
* %%
* Copyright (C) 2011 - 2015 Intuit Inc.
* %%
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
* #L%
*/
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.event.Observes;
import javax.enterprise.event.Reception;
import javax.inject.Inject;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.intuit.tank.api.cloud.VMTracker;
import com.intuit.tank.api.model.v1.cloud.CloudVmStatus;
import com.intuit.tank.api.model.v1.cloud.CloudVmStatusContainer;
import com.intuit.tank.dao.JobInstanceDao;
import com.intuit.tank.dao.JobNotificationDao;
import com.intuit.tank.project.EntityVersion;
import com.intuit.tank.project.JobInstance;
import com.intuit.tank.project.JobNotification;
import com.intuit.tank.vm.api.enumerated.JobLifecycleEvent;
import com.intuit.tank.vm.api.enumerated.RecipientType;
import com.intuit.tank.vm.api.enumerated.VMRegion;
import com.intuit.tank.vm.event.JobEvent;
import com.intuit.tank.vm.vmManager.Recipient;
import com.intuit.tank.vmManager.environment.amazon.CloudwatchInstance;
@ApplicationScoped
public class CloudWatchObserver {
private static final Logger LOG = LogManager.getLogger(CloudWatchObserver.class);
@Inject
private JobInstanceDao dao;
@Inject
private JobNotificationDao notificationDao;
@Inject
private VMTracker vmTracker;
/**
*
* @param jobEvent
*/
public void observe(@Observes(notifyObserver = Reception.ALWAYS) JobEvent jobEvent) {
if (jobEvent.getEvent() == JobLifecycleEvent.AGENT_STARTED) {
JobInstance job = dao.findById(Integer.valueOf(jobEvent.getJobId()));
for (EntityVersion version : job.getNotificationVersions()) {
JobNotification not = notificationDao.findById(version.getObjectId());
if (not != null && not.getLifecycleEvents() != null
&& not.getLifecycleEvents().contains(JobLifecycleEvent.AGENT_EXCESSIVE_CPU)) {
LOG.info("Adding watches for job " + job.getId());
addWatches(job, not);
break;
}
}
} else if (jobEvent.getEvent() == JobLifecycleEvent.JOB_FINISHED) {
JobInstance job = dao.findById(Integer.valueOf(jobEvent.getJobId()));
for (EntityVersion version : job.getNotificationVersions()) {
JobNotification not = notificationDao.findById(version.getObjectId());
if (not != null && not.getLifecycleEvents() != null
&& not.getLifecycleEvents().contains(JobLifecycleEvent.AGENT_EXCESSIVE_CPU)) {
LOG.info("Adding watches for job " + job.getId());
removeWatches(job, not);
break;
}
}
}
}
/**
*
* @param job
* @param not
*/
private void addWatches(final JobInstance job, final JobNotification not) {
new Thread(new Runnable() {
public void run() {
String jobId = Integer.toString(job.getId());
CloudVmStatusContainer vmStatusForJob = vmTracker.getVmStatusForJob(jobId);
Set<CloudVmStatus> statuses = vmStatusForJob.getStatuses();
Map<VMRegion, Set<String>> instanceMap = new HashMap<VMRegion, Set<String>>();
for (CloudVmStatus s : statuses) {
s.getVmRegion();
Set<String> set = instanceMap.get(s.getVmRegion());
if (set == null) {
set = new HashSet<String>();
instanceMap.put(s.getVmRegion(), set);
}
set.add(s.getInstanceId());
}
for (Entry<VMRegion, Set<String>> entry : instanceMap.entrySet()) {
CloudwatchInstance cwInstance = new CloudwatchInstance(entry.getKey());
for (Recipient recip : not.getRecipients()) {
if (recip.getType() == RecipientType.email) {
String email = recip.getAddress();
cwInstance.addWatch(entry.getValue(), email, jobId);
}
}
}
}
}).start();
}
/**
*
* @param job
* @param not
*/
private void removeWatches(final JobInstance job, final JobNotification not) {
new Thread(new Runnable() {
public void run() {
String jobId = Integer.toString(job.getId());
CloudVmStatusContainer vmStatusForJob = vmTracker.getVmStatusForJob(jobId);
Set<CloudVmStatus> statuses = vmStatusForJob.getStatuses();
Map<VMRegion, Set<String>> instanceMap = new HashMap<VMRegion, Set<String>>();
for (CloudVmStatus s : statuses) {
s.getVmRegion();
Set<String> set = instanceMap.get(s.getVmRegion());
if (set == null) {
set = new HashSet<String>();
instanceMap.put(s.getVmRegion(), set);
}
set.add(s.getInstanceId());
}
for (VMRegion vmRegion : instanceMap.keySet()) {
CloudwatchInstance cwInstance = new CloudwatchInstance(vmRegion);
for (Recipient recip : not.getRecipients()) {
if (recip.getType() == RecipientType.email) {
String email = recip.getAddress();
cwInstance.removeWatch(email, jobId);
}
}
}
}
}).start();
}
}