package io.cattle.platform.api.pubsub.manager; import io.cattle.platform.api.auth.Policy; import io.cattle.platform.api.pubsub.model.Subscribe; import io.cattle.platform.api.pubsub.subscribe.SubscriptionHandler; import io.cattle.platform.api.pubsub.util.SubscriptionUtils; import io.cattle.platform.api.pubsub.util.SubscriptionUtils.SubscriptionStyle; import io.cattle.platform.api.utils.ApiUtils; import io.cattle.platform.framework.event.FrameworkEvents; import io.github.ibuildthecloud.gdapi.condition.Condition; import io.github.ibuildthecloud.gdapi.context.ApiContext; import io.github.ibuildthecloud.gdapi.factory.SchemaFactory; import io.github.ibuildthecloud.gdapi.model.ListOptions; import io.github.ibuildthecloud.gdapi.request.ApiRequest; import io.github.ibuildthecloud.gdapi.request.resource.impl.AbstractNoOpResourceManager; import io.github.ibuildthecloud.gdapi.util.ProxyUtils; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeSet; import javax.inject.Inject; import org.apache.commons.lang3.StringUtils; public class SubscribeManager extends AbstractNoOpResourceManager { List<SubscriptionHandler> handlers = new ArrayList<SubscriptionHandler>(); @Override public Class<?>[] getTypeClasses() { return new Class<?>[] { Subscribe.class }; } @Override protected Object createInternal(String type, ApiRequest request) { List<String> eventNames = getEventNames(request); Set<String> filteredEventNames = new TreeSet<String>(); Policy policy = ApiUtils.getPolicy(); SubscriptionStyle style = SubscriptionUtils.getSubscriptionStyle(policy); for (String eventName : eventNames) { switch (style) { case QUALIFIED: if (eventName.contains(FrameworkEvents.EVENT_SEP)) { eventName = StringUtils.substringBefore(eventName, FrameworkEvents.EVENT_SEP); } String key = SubscriptionUtils.getSubscriptionQualifier(policy); String value = SubscriptionUtils.getSubscriptionQualifierValue(policy); eventName = String.format("%s%s%s=%s", eventName, FrameworkEvents.EVENT_SEP, key, value); break; case RAW: break; } filteredEventNames.add(eventName); } request.setResponseContentType("text/plain"); try { for (SubscriptionHandler handler : handlers) { if (handler.subscribe(filteredEventNames, request, style != SubscriptionStyle.RAW)) { return new Object(); } } } catch (IOException e) { throw new IllegalStateException("Failed to subscribe to [" + filteredEventNames + "]", e); } return super.createInternal(type, request); } protected List<String> getEventNames(ApiRequest request) { Subscribe subscribe = request.proxyRequestObject(Subscribe.class); List<String> eventNames = subscribe.getEventNames(); if (eventNames != null) { return eventNames; } eventNames = new ArrayList<String>(); Map<String, List<Condition>> conditions = request.getConditions(); if (conditions == null) { return eventNames; } @SuppressWarnings({ "unchecked", "rawtypes" }) List<?> list = ProxyUtils.proxy((Map) conditions, Subscribe.class).getEventNames(); if (list != null) { for (Object condition : list) { if (condition instanceof Condition) { Object value = ((Condition) condition).getValue(); if (value != null) { eventNames.add(value.toString()); } } } } return eventNames; } @Override protected Object listInternal(SchemaFactory schemaFactory, String type, Map<Object, Object> criteria, ListOptions options) { return createInternal(type, ApiContext.getContext().getApiRequest()); } public List<SubscriptionHandler> getHandlers() { return handlers; } @Inject public void setHandlers(List<SubscriptionHandler> handlers) { this.handlers = handlers; } }