package com.clouck.service; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.commons.lang3.Validate; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.clouck.application.SystemCache; import com.clouck.comparator.Ec2Comparator; import com.clouck.exception.CloudVersionEc2CompparatorNotFoundException; import com.clouck.model.Account; import com.clouck.model.Event; import com.clouck.model.EventType; import com.clouck.model.Region; import com.clouck.model.ResourceType; import com.clouck.model.aws.AbstractResource; import com.clouck.model.aws.ec2.Ec2Version; import com.clouck.model.aws.ec2.Ec2VersionMeta; import com.clouck.repository.EventRepository; import com.clouck.util.ResourceUtil; import com.clouck.validator.Ec2ResourceValidator; import com.clouck.wrapper.rabbit.MQWrapper; import com.google.common.base.Optional; @Service public class EventServiceImpl implements EventService { private static final Logger log = LoggerFactory.getLogger(EventServiceImpl.class); @Autowired private AccountService accountService; @Autowired private AwsService awsService; @Autowired private EventRepository eventDao; @Autowired private BaseService baseService; @Autowired private Ec2ResourceValidator validator; @Autowired private SystemCache systemCache; @Autowired private ConfService confService; @Autowired private MQWrapper mQWrapper; @Autowired private ResourceUtil resourceUtil; @Override public void generateEvents(Account account) { Validate.notNull(account); log.debug("============generate events for account:({})============", account.getId() + "==>" + account.getName()); for (ResourceType resourceType : ResourceType.findViewResourceTypes()) { if (resourceType.isMultiRegion()) { for (Region region : Region.findAvailableRegions(resourceType)) { mQWrapper.sendGenerateEventMessage(account.getId(), resourceType, region); } } else { mQWrapper.sendGenerateEventMessage(account.getId(), resourceType); } } log.debug("============ end generate events for account:({})============", account.getId() + "==>" + account.getName()); } @Override public List<Ec2VersionMeta> generateEvents(List<Ec2Version> ec2Versions) { Validate.notNull(ec2Versions); Validate.isTrue(ec2Versions.size() > 0); List<Ec2VersionMeta> result = new ArrayList<>(); for (int i = 0; i < ec2Versions.size() - 1; i++) { result.add(generateEvents(ec2Versions.get(i), ec2Versions.get(i + 1))); } return result; } @Override public Ec2VersionMeta generateEvents(Ec2Version oldVersion, Ec2Version newVersion) { validator.validate(oldVersion, newVersion); Ec2VersionMeta result = new Ec2VersionMeta(oldVersion.getAccountId(), oldVersion.getResourceType(), oldVersion.getRegion(), oldVersion.getId(), newVersion.getId(), newVersion.getTimeDetected()); List<AbstractResource<?>> oldResources = awsService.findResources(oldVersion.getResourceIds(), oldVersion.getResourceType()); List<AbstractResource<?>> newResources = awsService.findResources(newVersion.getResourceIds(), newVersion.getResourceType()); List<Event> events = generateEvents(oldResources, newResources); result.setEvents(events); return result; } @Override public Ec2VersionMeta generateEvents(Ec2Version firstEc2Version) { Validate.notNull(firstEc2Version); String accountId = firstEc2Version.getAccountId(); ResourceType resourceType = firstEc2Version.getResourceType(); Region region = firstEc2Version.getRegion(); Date dt = firstEc2Version.getTimeDetected(); Validate.noNullElements(new Object[]{accountId, resourceType, region, dt}); Validate.isTrue(awsService.countEc2VersionsUpto(accountId, resourceType, region, new DateTime(dt), true) == 1); List<Event> events = new ArrayList<>(); events.add(firstScan(resourceType)); List<AbstractResource<?>> newResources = awsService.findResources(firstEc2Version.getResourceIds(), resourceType); for (AbstractResource<?> newResource : newResources) { events.add(initialise(newResource)); } Ec2VersionMeta result = new Ec2VersionMeta(accountId, resourceType, region, null, firstEc2Version.getId(), dt); result.setEvents(events); return result; } @Override public List<Event> generateEvents(List<AbstractResource<?>> oldResources, List<AbstractResource<?>> newResources) { validator.validate(oldResources, newResources); List<Event> result = new ArrayList<>(); Map<String, AbstractResource<?>> oldKeyMap = resourceUtil.generateKeyMap(oldResources); Map<String, AbstractResource<?>> newKeyMap = resourceUtil.generateKeyMap(newResources); for (String uniqueId : newKeyMap.keySet()) { AbstractResource<?> newResource = newKeyMap.get(uniqueId); AbstractResource<?> oldResource = oldKeyMap.get(uniqueId); if (oldResource != null) { //if their are same, don't need to generate update events. //this can prevent generate an unknown event if (!oldResource.equals(newResource)) { log.debug("unique id {} found, generate update events", uniqueId); result.addAll(update(oldResource, newResource)); } else { log.debug("oldResource {} and newResource {} are equal", oldResource.getId(), newResource.getId()); } } else { log.debug("unique id {} not found, generate add events", uniqueId); result.add(add(newResource)); } oldKeyMap.remove(uniqueId); } for (AbstractResource<?> deletedResource : oldKeyMap.values()) { log.debug("unique id {} not exist, generate delete events", deletedResource.getUniqueId()); result.add(delete(deletedResource)); } Validate.isTrue(result.size() > 0); return result; } @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Event initialise(AbstractResource<?> newResource) { Ec2Comparator comparator = systemCache.findComparator(newResource.getClass()); return comparator.initialise(newResource); } @SuppressWarnings("rawtypes") public Event firstScan(ResourceType resourceType) { Ec2Comparator comparator = systemCache.findComparator(resourceType.getResourceClass()); return comparator.firstScan(); } @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Event add(AbstractResource<?> newResource) { Ec2Comparator comparator = systemCache.findComparator(newResource.getClass()); return comparator.add(newResource); } @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public Event delete(AbstractResource<?> oldResource) { Ec2Comparator comparator = systemCache.findComparator(oldResource.getClass()); return comparator.delete(oldResource); } @Override @SuppressWarnings({ "rawtypes", "unchecked" }) public List<Event> update(AbstractResource<?> oldResource, AbstractResource<?> newResource) { Validate.isTrue(oldResource.getClass().equals(newResource.getClass())); Ec2Comparator comparator = systemCache.findComparator(newResource.getClass()); return comparator.update(oldResource, newResource); } // //// private static Ordering<AbstractEvent> ordering = new Ordering<AbstractEvent>() { //// public int compare(AbstractEvent left, AbstractEvent right) { //// return Longs.compare(left.getId(), right.getId()); //// } //// }; //// //// @Override //// public List<AbstractEvent> findAscTop10EventsSince(Account account, Long eventId) { //// //// List<AbstractEvent> events = eventDao.findDescTop10EventsSince(account, eventId); //// Collections.sort(events, ordering); //// return events; //// } // // @Override // public List<Event> findEvents(String accountId, int size) { // return eventDao.findEvents(accountId, size); // } @Override public List<Event> findEvents(Set<String> newEc2VersionIds) { return eventDao.findEvents(newEc2VersionIds); } @Override public List<Event> findEventsByResourceId(String resourceId) { return eventDao.findEventsByResourceId(resourceId); } @Override public List<Event> findEventsByUniqueId(String uniqueId) { return eventDao.findEventsByUniqueId(uniqueId); } }