OffloadingBrowserServlet.java 13.2 KB
/*
 * Decompiled with CFR 0_118.
 * 
 * Could not load the following classes:
 *  javax.servlet.ServletException
 *  org.apache.commons.lang.StringUtils
 *  org.apache.felix.scr.annotations.Reference
 *  org.apache.felix.scr.annotations.sling.SlingServlet
 *  org.apache.sling.api.SlingHttpServletRequest
 *  org.apache.sling.api.SlingHttpServletResponse
 *  org.apache.sling.api.request.RequestPathInfo
 *  org.apache.sling.api.servlets.SlingAllMethodsServlet
 *  org.apache.sling.commons.json.JSONArray
 *  org.apache.sling.commons.json.JSONException
 *  org.apache.sling.commons.json.JSONObject
 *  org.apache.sling.discovery.ClusterView
 *  org.apache.sling.discovery.DiscoveryService
 *  org.apache.sling.discovery.InstanceDescription
 *  org.apache.sling.discovery.InstanceFilter
 *  org.apache.sling.discovery.TopologyView
 *  org.slf4j.Logger
 *  org.slf4j.LoggerFactory
 */
package com.adobe.granite.offloading.impl.servlets;

import com.adobe.granite.offloading.api.InstanceNetworkInfoService;
import com.adobe.granite.offloading.api.OffloadingTopicManager;
import com.adobe.granite.offloading.api.TopicInstancesHolder;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.servlet.ServletException;
import org.apache.commons.lang.StringUtils;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.sling.SlingServlet;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.request.RequestPathInfo;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.commons.json.JSONArray;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.JSONObject;
import org.apache.sling.discovery.ClusterView;
import org.apache.sling.discovery.DiscoveryService;
import org.apache.sling.discovery.InstanceDescription;
import org.apache.sling.discovery.InstanceFilter;
import org.apache.sling.discovery.TopologyView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SlingServlet(resourceTypes={"granite/offloading/components/view"}, methods={"GET"}, extensions={"json"}, selectors={"list"})
public class OffloadingBrowserServlet
extends SlingAllMethodsServlet {
    private static final Logger LOG = LoggerFactory.getLogger(OffloadingBrowserServlet.class);
    public static final String JSON_KEY_SLING_ID = "slingID";
    public static final String JSON_KEY_INSTANCE_IP = "ip";
    public static final String JSON_KEY_INSTANCE_PORT = "port";
    public static final String JSON_KEY_INSTANCES = "instances";
    public static final String JSON_KEY_DISABLED_DO_TO_WHITELISTING = "disabledDueToWhitelisting";
    public static final String JSON_KEY_TOPICS = "topics";
    public static final String JSON_KEY_TOPIC = "topic";
    public static final String JSON_KEY_CLUSTER = "cluster";
    public static final String JSON_KEY_INSTANCE_IS_LEADER = "isLeader";
    public static final String JSON_KEY_INSTANCE_IS_LOCAL = "isLocal";
    public static final String JSON_KEY_TOPIC_ENABLED = "topicEnabled";
    public static final String JSON_KEY_TOPIC_EXCLUSIVE = "topicExclusive";
    @Reference
    private DiscoveryService ds;
    @Reference
    private OffloadingTopicManager otm;
    @Reference
    private InstanceNetworkInfoService inis;

    protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response) throws ServletException, IOException {
        String clusterID;
        response.setContentType("application/json");
        RequestPathInfo rpi = request.getRequestPathInfo();
        String[] selectors = rpi.getSelectors();
        JSONObject jsonResponse = new JSONObject();
        if (selectors.length == 1) {
            try {
                this.prepareAllInstancesJSONResponse(jsonResponse);
            }
            catch (JSONException e) {
                LOG.error("Unable to create all instances JSON response.", (Throwable)e);
            }
        } else if (selectors.length == 2) {
            clusterID = selectors[1];
            try {
                this.prepareClusterDetailsJSONResponse(jsonResponse, clusterID);
            }
            catch (JSONException e) {
                LOG.error("Unable to create cluster details JSON response for cluster with ID " + clusterID, (Throwable)e);
            }
        } else if (selectors.length == 3) {
            clusterID = selectors[1];
            String slingID = selectors[2];
            try {
                this.prepareInstanceDetailsJSONResponse(jsonResponse, clusterID, slingID);
            }
            catch (JSONException e) {
                LOG.error("Unable to create instance details JSON response for instance with ID " + slingID, (Throwable)e);
            }
        }
        PrintWriter out = response.getWriter();
        out.write(jsonResponse.toString());
    }

    private void prepareAllInstancesJSONResponse(JSONObject jsonResponse) throws JSONException {
        Map<String, TopicInstancesHolder> topicToInstancesMap = this.otm.getInstances();
        if (!topicToInstancesMap.isEmpty()) {
            TreeSet<String> topics = new TreeSet<String>(topicToInstancesMap.keySet());
            JSONArray topicToInstancesArray = new JSONArray();
            for (String topic : topics) {
                int instancePort;
                Set<String> ipSet;
                String slingID;
                String instanceIP;
                JSONObject topicToInstances = new JSONObject();
                topicToInstances.put("topic", (Object)topic);
                TopicInstancesHolder holder = topicToInstancesMap.get(topic);
                Set<InstanceDescription> enabledInstances = holder.getEnabledInstances();
                Set<InstanceDescription> disabledInstances = holder.getDisabledInstances();
                JSONArray instancesJSONArray = new JSONArray();
                for (InstanceDescription instance2 : enabledInstances) {
                    slingID = instance2.getSlingId();
                    instanceIP = "";
                    instancePort = this.inis.getListeningPort(instance2);
                    ipSet = this.inis.getListeningAddresses(instance2);
                    if (!ipSet.isEmpty()) {
                        instanceIP = ipSet.iterator().next();
                    }
                    JSONObject instanceJSON = new JSONObject();
                    instanceJSON.put("slingID", (Object)slingID);
                    instanceJSON.put("ip", (Object)instanceIP);
                    instanceJSON.put("port", instancePort);
                    instanceJSON.put("cluster", (Object)instance2.getClusterView().getId());
                    instanceJSON.put("topicEnabled", true);
                    instanceJSON.put("disabledDueToWhitelisting", false);
                    instancesJSONArray.put((Object)instanceJSON);
                }
                for (InstanceDescription instance2 : disabledInstances) {
                    slingID = instance2.getSlingId();
                    instanceIP = "";
                    instancePort = this.inis.getListeningPort(instance2);
                    ipSet = this.inis.getListeningAddresses(instance2);
                    if (!ipSet.isEmpty()) {
                        instanceIP = ipSet.iterator().next();
                    }
                    Set<String> blacklist = this.otm.getBlacklistedTopics(instance2);
                    boolean disabledDueToWhitelisting = true;
                    for (String t : blacklist) {
                        if (!t.equals(topic)) continue;
                        disabledDueToWhitelisting = false;
                        break;
                    }
                    JSONObject instanceJSON = new JSONObject();
                    instanceJSON.put("slingID", (Object)slingID);
                    instanceJSON.put("ip", (Object)instanceIP);
                    instanceJSON.put("port", instancePort);
                    instanceJSON.put("cluster", (Object)instance2.getClusterView().getId());
                    instanceJSON.put("topicEnabled", false);
                    instanceJSON.put("disabledDueToWhitelisting", disabledDueToWhitelisting);
                    instancesJSONArray.put((Object)instanceJSON);
                }
                topicToInstances.put("instances", (Object)instancesJSONArray);
                topicToInstancesArray.put((Object)topicToInstances);
            }
            jsonResponse.put("topics", (Object)topicToInstancesArray);
        }
    }

    private void prepareClusterDetailsJSONResponse(JSONObject jsonResponse, String clusterID) throws JSONException {
        TopologyView topologyView = this.ds.getTopology();
        Set clusters = topologyView.getClusterViews();
        ClusterView cluster = null;
        for (ClusterView c : clusters) {
            if (!clusterID.equals(c.getId())) continue;
            cluster = c;
            break;
        }
        if (cluster != null) {
            JSONArray instancesArray = new JSONArray();
            List instances = cluster.getInstances();
            for (InstanceDescription instance : instances) {
                JSONObject instanceJSON = new JSONObject();
                instanceJSON.put("slingID", (Object)instance.getSlingId());
                instanceJSON.put("isLeader", instance.isLeader());
                instanceJSON.put("isLocal", instance.isLocal());
                instancesArray.put((Object)instanceJSON);
            }
            jsonResponse.put("cluster", (Object)clusterID);
            jsonResponse.put("instances", (Object)instancesArray);
        }
    }

    private void prepareInstanceDetailsJSONResponse(JSONObject jsonResponse, String clusterID, final String instanceID) throws JSONException {
        InstanceDescription instance;
        InstanceFilter filter = new InstanceFilter(){

            public boolean accept(InstanceDescription instanceDescription) {
                return instanceID.equals(instanceDescription.getSlingId());
            }
        };
        TopologyView topologyView = this.ds.getTopology();
        Set filteredInstances = topologyView.findInstances(filter);
        if (filteredInstances != null && filteredInstances.size() == 1 && (instance = (InstanceDescription)filteredInstances.toArray()[0]) != null) {
            String slingID = instance.getSlingId();
            String instanceIP = "";
            int instancePort = this.inis.getListeningPort(instance);
            Set<String> ipSet = this.inis.getListeningAddresses(instance);
            if (!ipSet.isEmpty()) {
                instanceIP = ipSet.iterator().next();
            }
            jsonResponse.put("slingID", (Object)slingID);
            jsonResponse.put("ip", (Object)instanceIP);
            jsonResponse.put("port", instancePort);
            jsonResponse.put("cluster", (Object)clusterID);
            String registeredTopicsString = instance.getProperty("com.adobe.granite.offloading.job.registeredtopics");
            String whitelistTopicsString = instance.getProperty("job.consumermanager.whitelist");
            String activeTopics = instance.getProperty("org.apache.sling.event.jobs.consumer.topics");
            if (StringUtils.isNotEmpty((String)registeredTopicsString)) {
                String[] registeredTopics = registeredTopicsString.split(",");
                JSONArray topicsJSONArray = new JSONArray();
                for (String topic : registeredTopics) {
                    boolean topicIsExclusive = this.isTopicIn(topic, whitelistTopicsString);
                    boolean topicIsEnabled = this.isTopicIn(topic, activeTopics);
                    JSONObject topicJSON = new JSONObject();
                    topicJSON.put("topic", (Object)topic);
                    topicJSON.put("topicEnabled", topicIsEnabled);
                    topicJSON.put("topicExclusive", topicIsExclusive);
                    topicsJSONArray.put((Object)topicJSON);
                }
                jsonResponse.put("topics", (Object)topicsJSONArray);
            }
        }
    }

    private boolean isTopicIn(String topic, String topicsString) {
        if (StringUtils.isNotEmpty((String)topicsString)) {
            String[] topics;
            for (String t : topics = topicsString.split(",")) {
                if (!topic.equals(t)) continue;
                return true;
            }
        }
        return false;
    }

    protected void bindDs(DiscoveryService discoveryService) {
        this.ds = discoveryService;
    }

    protected void unbindDs(DiscoveryService discoveryService) {
        if (this.ds == discoveryService) {
            this.ds = null;
        }
    }

    protected void bindOtm(OffloadingTopicManager offloadingTopicManager) {
        this.otm = offloadingTopicManager;
    }

    protected void unbindOtm(OffloadingTopicManager offloadingTopicManager) {
        if (this.otm == offloadingTopicManager) {
            this.otm = null;
        }
    }

    protected void bindInis(InstanceNetworkInfoService instanceNetworkInfoService) {
        this.inis = instanceNetworkInfoService;
    }

    protected void unbindInis(InstanceNetworkInfoService instanceNetworkInfoService) {
        if (this.inis == instanceNetworkInfoService) {
            this.inis = null;
        }
    }

}