package alien4cloud.paas; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledFuture; import javax.annotation.PostConstruct; import javax.annotation.Resource; import javax.inject.Inject; import org.springframework.beans.factory.annotation.Value; import org.springframework.scheduling.TaskScheduler; import org.springframework.stereotype.Component; import com.google.common.collect.Maps; import alien4cloud.dao.IGenericSearchDAO; import alien4cloud.exception.AlreadyExistException; import alien4cloud.orchestrators.plugin.IOrchestratorPlugin; import alien4cloud.paas.exception.OrchestratorDisabledException; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; /** * Manages the paas providers currently used by an enabled Cloud in ALIEN. */ @Slf4j @Component public class OrchestratorPluginService implements IPaasEventService { @Resource(name = "alien-es-dao") private IGenericSearchDAO alienDao; @Resource(name = "alien-monitor-es-dao") private IGenericSearchDAO alienMonitorDao; @Resource(name = "paas-monitor-scheduler") private TaskScheduler scheduler; /** Interval in milliseconds on which to retrieve monitoring events from a PaaS provider. */ @Value("${paas_monitor.monitor_interval_ms}") private long monitorIntervalMs = 1000 * 30; @Inject private DeploymentStatusEventHandler deploymentStatusEventHandler; private Map<String, Registration> monitorRegistrations = Maps.newHashMap(); @SuppressWarnings("rawtypes") private List<IPaasEventListener> listeners = Collections.synchronizedList(new ArrayList<IPaasEventListener>()); public OrchestratorPluginService() { log.info("Create new PaaSProvider instance."); } @Override public void addListener(IPaasEventListener<?> listener) { listeners.add(listener); } @PostConstruct public void init() { // Deployment status event handler should be the first handler has quite important. listeners.add(0, deploymentStatusEventHandler); } /** * Register an {@link IOrchestratorPlugin} for a given cloud. * * @param orchestratorId Id of the cloud. * @param instance Instance of the IOrchestratorPlugin for the given cloud. */ public void register(String orchestratorId, IOrchestratorPlugin instance) { log.info("Register provider with id {}", orchestratorId); if (monitorRegistrations.containsKey(orchestratorId)) { throw new AlreadyExistException("Cloud [" + orchestratorId + "] has already been registered"); } // create the polling monitor responsible to monitor this instance. PaaSProviderPollingMonitor monitor = new PaaSProviderPollingMonitor(alienDao, alienMonitorDao, instance, listeners, orchestratorId); ScheduledFuture<?> monitorFuture = scheduler.scheduleAtFixedRate(monitor, monitorIntervalMs); Registration registration = new Registration(instance, monitorFuture); monitorRegistrations.put(orchestratorId, registration); } /** * Remove the registration for the given cloud (will stop monitoring the cloud using the registered IOrchestratorPlugin). * * @param orchestratorId The id of the cloud for which to remove registration. */ public IOrchestratorPlugin unregister(String orchestratorId) { log.info("Unregister provider with id {}", orchestratorId); Registration registration = monitorRegistrations.remove(orchestratorId); if (registration != null) { registration.registration.cancel(false); return registration.instance; } else { return null; } } /** * Get a registered IOrchestratorPlugin for a cloud. * * @param orchestratorId The id of the cloud for which to get the IOrchestratorPlugin instance. * @return The {@link IOrchestratorPlugin} for the given cloud or null if none is registered for the given cloud id. */ public IOrchestratorPlugin get(String orchestratorId) { Registration registration = monitorRegistrations.get(orchestratorId); return registration == null ? null : registration.instance; } /** * Get a registered IOrchestratorPlugin for a cloud. * * @param orchestratorId The id of the cloud for which to get the IOrchestratorPlugin instance. * @return The {@link IOrchestratorPlugin} for the given cloud or throw OrchestratorDisabledException if none is registered for the given cloud id. */ public IOrchestratorPlugin getOrFail(String orchestratorId) { Registration registration = monitorRegistrations.get(orchestratorId); if (registration == null) { throw new OrchestratorDisabledException("The orchestrator with id <" + orchestratorId + "> is not enabled or loaded yet."); } return registration == null ? null : registration.instance; } /** * A registration for a paasProvider and the associated monitoring registration. */ @AllArgsConstructor(suppressConstructorProperties = true) private class Registration { private IOrchestratorPlugin instance; private ScheduledFuture<?> registration; } }