package io.cattle.platform.agent.impl; import io.cattle.platform.async.utils.AsyncUtils; import io.cattle.platform.async.utils.TimeoutException; import io.cattle.platform.core.constants.AgentConstants; import io.cattle.platform.core.constants.CommonStatesConstants; import io.cattle.platform.core.dao.AgentDao; import io.cattle.platform.eventing.EventCallOptions; import io.cattle.platform.eventing.EventListener; import io.cattle.platform.eventing.EventService; import io.cattle.platform.eventing.exception.AgentRemovedException; import io.cattle.platform.eventing.model.Event; import io.cattle.platform.eventing.model.EventVO; import io.cattle.platform.iaas.event.IaasEvents; import io.cattle.platform.iaas.event.delegate.DelegateEvent; import io.cattle.platform.json.JsonMapper; import java.util.Arrays; import java.util.HashSet; import java.util.Map; import java.util.Set; import com.google.common.util.concurrent.ListenableFuture; public class WrappedEventService implements EventService { public static final Set<String> GOOD_AGENT_STATES = new HashSet<String>(Arrays.asList(CommonStatesConstants.ACTIVATING, CommonStatesConstants.ACTIVE, AgentConstants.STATE_RECONNECTING)); long agentId; boolean delegate; EventService eventService; Map<String, Object> instanceData; EventService agentRequestPublisher; JsonMapper jsonMapper; AgentDao agentDao; public WrappedEventService(long agentId, boolean delegate, EventService eventService, Map<String, Object> instanceData, JsonMapper jsonMapper, AgentDao agentDao) { super(); this.agentId = agentId; this.delegate = delegate; this.eventService = eventService; this.instanceData = instanceData; this.jsonMapper = jsonMapper; this.agentDao = agentDao; } protected Event buildEvent(Event request) { Event event = null; Object payload = request.getData(); if (payload instanceof Event) { event = new EventVO<>((Event)payload).withReplyTo(((Event)payload).getName() + Event.REPLY_SUFFIX); } if (delegate) { event = new DelegateEvent(instanceData, event); } return new EventVO<>(event).withName(IaasEvents.appendAgent(event.getName(), agentId)); } @Override public boolean publish(Event request) { return eventService.publish(buildEvent(request)); } @Override public ListenableFuture<Event> call(final Event request, EventCallOptions callOptions) { Event unwrappedEvent = buildEvent(request); String state = agentDao.getAgentState(agentId); if (state == null) { return AsyncUtils.error(new AgentRemovedException("Agent [" + agentId + "] is removed", request)); } else if (!GOOD_AGENT_STATES.contains(state)) { return AsyncUtils.error(new TimeoutException()); } return EventCallProgressHelper.call(eventService, unwrappedEvent, Event.class, callOptions, new EventResponseMarshaller() { @SuppressWarnings("unchecked") @Override public <T> T convert(Event resultEvent, Class<T> reply) { Object payload = resultEvent; if (delegate) { payload = resultEvent.getData(); } return (T) new EventVO<>().withName(request.getReplyTo()).withData(payload); } }); } /* Boilerplate to implement interface */ @Override public ListenableFuture<?> subscribe(String eventName, EventListener listener) { throw new UnsupportedOperationException(); } @Override public void unsubscribe(String eventName, EventListener listener) { throw new UnsupportedOperationException(); } @Override public void unsubscribe(EventListener listener) { throw new UnsupportedOperationException(); } @Override public Event callSync(Event event, EventCallOptions callOptions) { return AsyncUtils.get(call(event, callOptions)); } }