package io.cattle.platform.servicediscovery.process; import io.cattle.platform.configitem.events.ConfigUpdate; import io.cattle.platform.configitem.model.Client; import io.cattle.platform.configitem.model.ItemVersion; import io.cattle.platform.configitem.version.ConfigItemStatusManager; import io.cattle.platform.core.dao.GenericResourceDao; import io.cattle.platform.core.dao.HostDao; import io.cattle.platform.core.model.Stack; import io.cattle.platform.eventing.EventService; import io.cattle.platform.eventing.annotation.AnnotatedEventListener; import io.cattle.platform.eventing.annotation.EventHandler; import io.cattle.platform.eventing.lock.EventLock; import io.cattle.platform.eventing.model.EventVO; import io.cattle.platform.json.JsonMapper; import io.cattle.platform.lock.LockCallbackNoReturn; import io.cattle.platform.lock.LockManager; import io.cattle.platform.object.ObjectManager; import io.cattle.platform.object.process.ObjectProcessManager; import io.cattle.platform.servicediscovery.deployment.impl.lock.StackHealthStateUpdateLock; import io.cattle.platform.servicediscovery.service.ServiceDiscoveryService; import java.io.IOException; import java.util.concurrent.Callable; import javax.inject.Inject; import javax.inject.Named; @Named public class StackHealthStateUpdate implements AnnotatedEventListener { @Inject ObjectProcessManager processManager; @Inject ConfigItemStatusManager itemManager; @Inject EventService eventService; @Inject ObjectManager objectManager; @Inject HostDao hostDao; @Inject LockManager lockManager; @Inject GenericResourceDao resourceDao; @Inject JsonMapper jsonMapper; @Inject ServiceDiscoveryService sdService; @EventHandler(lock = EventLock.class) public void stackUpdate(ConfigUpdate update) { if (update.getResourceId() == null) { return; } final Client client = new Client(Stack.class, new Long(update.getResourceId())); reconcileForClient(update, client, new Callable<Boolean>() { @Override public Boolean call() throws IOException { return process(client.getResourceId()); } }); } protected boolean process(long stackId) throws IOException { Stack stack = objectManager.loadResource(Stack.class, stackId); if (stack == null) { return true; } sdService.updateHealthState(stack); return true; } protected void reconcileForClient(final ConfigUpdate update, final Client client, final Callable<Boolean> run) { lockManager.lock(new StackHealthStateUpdateLock(client.getResourceId()), new LockCallbackNoReturn() { @Override public void doWithLockNoResult() { ItemVersion itemVersion = itemManager.getRequestedVersion(client, StackHealthStateUpdateTrigger.STACK); if (itemVersion == null) { return; } try { if (run.call()) { itemManager.setApplied(client, StackHealthStateUpdateTrigger.STACK, itemVersion); eventService.publish(EventVO.reply(update)); } } catch (Exception e) { throw new IllegalStateException("Failed to process stack health state update for [" + client.getResourceId() + "]", e); } } }); } }