Package com.linkedin.databus.client.request

Source Code of com.linkedin.databus.client.request.ClientStatsRequestProcessor

package com.linkedin.databus.client.request;
/*
*
* Copyright 2013 LinkedIn Corp. All rights reserved
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied.  See the License for the
* specific language governing permissions and limitations
* under the License.
*
*/


import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutorService;

import org.apache.log4j.Logger;
import org.jboss.netty.handler.codec.http.HttpMethod;

import com.linkedin.databus.client.DatabusHttpClientImpl;
import com.linkedin.databus.client.pub.DatabusRegistration;
import com.linkedin.databus.client.pub.DatabusV3Registration;
import com.linkedin.databus.client.pub.DbusPartitionInfo;
import com.linkedin.databus.client.pub.RegistrationId;
import com.linkedin.databus.client.pub.mbean.UnifiedClientStats;
import com.linkedin.databus.client.registration.DatabusMultiPartitionRegistration;
import com.linkedin.databus.core.monitoring.mbean.DbusEventsStatisticsCollector;
import com.linkedin.databus.core.monitoring.mbean.DbusEventsTotalStats;
import com.linkedin.databus.core.monitoring.mbean.StatsCollectors;
import com.linkedin.databus2.core.container.monitoring.mbean.DbusHttpTotalStats;
import com.linkedin.databus2.core.container.request.AbstractStatsRequestProcessor;
import com.linkedin.databus2.core.container.request.DatabusRequest;
import com.linkedin.databus2.core.container.request.InvalidRequestParamValueException;
import com.linkedin.databus2.core.container.request.RequestProcessingException;

public class ClientStatsRequestProcessor extends AbstractStatsRequestProcessor
{

  public static final String MODULE = ClientStatsRequestProcessor.class.getName();
  public static final Logger LOG = Logger.getLogger(MODULE);
  public static final String COMMAND_NAME = "clientStats";

  private final static String OUTBOUND_EVENTS_TOTAL_KEY = "outbound/events/total";
  private final static String OUTBOUND_EVENTS_SOURCES_KEY = "outbound/events/sources";
  private final static String OUTBOUND_EVENTS_SOURCE_PREFIX = "outbound/events/source/";
  private final static String OUTBOUND_EVENTS_CLIENTS_KEY = "outbound/events/clients";
  private final static String OUTBOUND_EVENTS_CLIENT_PREFIX = "outbound/events/client/";
  private final static String INBOUND_HTTP_TOTAL_KEY = "inbound/http/total";
  private final static String INBOUND_HTTP_SOURCES_KEY = "inbound/http/sources";
  private final static String INBOUND_HTTP_SOURCE_PREFIX = "inbound/http/source/";
  private final static String INBOUND_HTTP_RELAYS_KEY = "inbound/http/relays";
  private final static String INBOUND_HTTP_RELAYS_PREFIX = "inbound/http/relay/";
  private final static String INBOUND_EVENTS_TOTAL_KEY = "inbound/events/total";
  private final static String BOOTSTRAP_EVENTS_TOTAL_KEY = "bootstrap/events/total";
  private final static String INBOUND_EVENTS_SOURCES_KEY = "inbound/events/sources"// was "outbound/events/sources"


  /** Stream/relay events (inbound into client lib's event buffer) for the registration. */
  private final static String INBOUND_EVENTS_REG_KEY_PREFIX = "inbound/events/registration/";

  /** Bootstrap events (inbound into client lib's event buffer) for the registration. */
  private final static String BOOTSTRAP_EVENTS_REG_KEY_PREFIX = "bootstrap/events/registration/";

  /** Stream/relay-mode callbacks for the registration (outbound to consumer/app). */
  // This key is very poorly named...
  private final static String INBOUND_CALLBACKS_REG_KEY_PREFIX = "inbound/callbacks/registration/";

  /** Bootstrap-mode callbacks for the registration (outbound to consumer/app). */
  private final static String BOOTSTRAP_CALLBACKS_REG_KEY_PREFIX = "bootstrap/callbacks/registration/";

  /**
   * Unified relay/bootstrap statistics for the registration (both inbound to the client
   * lib's event buffer and outbound to the consumer/app, but mostly the latter).
   */
  // "Registration" might be misnomer?  Client impl's loop is over relay groups, each
  // corresponding to a set of subscriptions (sources) and each with its own UnifiedClientStats
  // object.
  private final static String UNIFIED_REG_KEY_PREFIX = "unified/registration/";
  /**
   * Unified relay/bootstrap statistics aggregated across registrations (both inbound to
   * the client lib's event buffer and outbound to the consumer/app, but mostly the latter).
   */
  // Note that there is currently no corresponding REST interface to the aggregated
  // ConsumerCallbackStats objects.
  private final static String UNIFIED_TOTAL_KEY = "unified/total";

  private final DatabusHttpClientImpl _client;

  public ClientStatsRequestProcessor(ExecutorService executorService, DatabusHttpClientImpl client)
  {
    super(COMMAND_NAME, executorService);
    _client = client;
  }

  @Override
  public boolean doProcess(String category, DatabusRequest request)
         throws IOException, RequestProcessingException
  {
    boolean success = true;

    if (category.equals(OUTBOUND_EVENTS_TOTAL_KEY))
    {
      processEventsTotalStats(_client.getOutboundEventStatisticsCollector(), request);
    }
    else if (category.equals(OUTBOUND_EVENTS_SOURCES_KEY))
    {
      processEventsSourcesList(_client.getOutboundEventStatisticsCollector(), request);
    }
    else if (category.startsWith(OUTBOUND_EVENTS_SOURCE_PREFIX))
    {
      processEventsSourceStats(_client.getOutboundEventStatisticsCollector(),
                               OUTBOUND_EVENTS_SOURCE_PREFIX,
                               request);
    }
    else if (category.equals(OUTBOUND_EVENTS_CLIENTS_KEY))
    {
      processEventsPeersList(_client.getOutboundEventStatisticsCollector(), request);
    }
    else if (category.startsWith(OUTBOUND_EVENTS_CLIENT_PREFIX))
    {
      processEventsPeerStats(_client.getOutboundEventStatisticsCollector(),
                             OUTBOUND_EVENTS_CLIENT_PREFIX,
                             request);
    }
    else if (category.equals(INBOUND_HTTP_TOTAL_KEY))
    {
      processOutboundHttpTotalStats(request);
    }
    else if (category.equals(INBOUND_HTTP_SOURCES_KEY))
    {
      processOutboundHttpSourcesList(request);
    }
    else if (category.startsWith(INBOUND_HTTP_SOURCE_PREFIX))
    {
      processOutboundHttpSourceStats(request);
    }
    else if (category.equals(INBOUND_HTTP_RELAYS_KEY))
    {
      processOutboundHttpClientsList(request);
    }
    else if (category.startsWith(INBOUND_HTTP_RELAYS_PREFIX))
    {
      processOutboundHttpClientStats(request);
    }
    else if (category.equals(INBOUND_EVENTS_TOTAL_KEY))
    {
      processEventsTotalStats(_client.getInboundEventStatisticsCollector(), request);
    }
    else if (category.equals(BOOTSTRAP_EVENTS_TOTAL_KEY))
    {
      processEventsTotalStats(_client.getBootstrapEventsStatsCollector(), request);
    }
    else if (category.equals(INBOUND_EVENTS_SOURCES_KEY))
    {
      processEventsSourcesList(_client.getInboundEventStatisticsCollector(), request);
    }
    else if (category.startsWith(INBOUND_EVENTS_REG_KEY_PREFIX))
    {
      /**
       * TODO :  The reason why there is diverging code below is because V2 and V3 is using different registration objects
       * which results in different containers for V2 and V3 registrations.
       * Once we make V3 use DatabusRegistration, we should be having one call.
       *
       * Note: Couldnt use instanceof for differentiating V2/V3 as V3 Client is not visible here.
       */
       if ( _client.getClass().getSimpleName().equalsIgnoreCase("DatabusHttpClientImpl") )
         processInboundEventsRegistration(request);
       else
         processInboundEventsRegistrationV3(request);
    }
    else if (category.startsWith(BOOTSTRAP_EVENTS_REG_KEY_PREFIX))
    {
        /**
         * TODO :  The reason why there is diverging code below is because V2 and V3 is using different registration objects
         * which results in different containers for V2 and V3 registrations.
         * Once we make V3 use DatabusRegistration, we should be having one call.
         *
         *   Note: Couldnt use instanceof for differentiating V2/V3 as V3 Client is not visible here.
         */
       if ( _client.getClass().getSimpleName().equalsIgnoreCase("DatabusHttpClientImpl") )
         processBootstrapEventsRegistration(request);
       else
         processBootstrapEventsRegistrationV3(request);
    }
    else if (category.startsWith(INBOUND_CALLBACKS_REG_KEY_PREFIX))
    {
        /**
         * TODO :  The reason why there is diverging code below is because V2 and V3 is using different registration objects
         * which results in different containers for V2 and V3 registrations.
         * Once we make V3 use DatabusRegistration, we should be having one call.
         *
         * Note: Couldnt use instanceof for differentiating V2/V3 as V3 Client is not visible here.
         */
       if ( _client.getClass().getSimpleName().equalsIgnoreCase("DatabusHttpClientImpl") )
         processInboundCallbacksRegistration(request);
       else
         processInboundCallbacksRegistrationV3(request);
    }
    else if (category.startsWith(BOOTSTRAP_CALLBACKS_REG_KEY_PREFIX))
    {
        /**
         * TODO : The reason why there is diverging code below is because V2 and V3 is using different registration objects
         * which results in different containers for V2 and V3 registrations.
         * Once we make V3 use DatabusRegistration, we should be having one call.
         *
         * Note: Couldnt use instanceof for differentiating V2/V3 as V3 Client is not visible here.
         */
       if ( _client.getClass().getSimpleName().equalsIgnoreCase("DatabusHttpClientImpl") )
         processBootstrapCallbacksRegistration(request);
       else
         processBootstrapCallbacksRegistrationV3(request);
    }
    else if (category.startsWith(UNIFIED_REG_KEY_PREFIX))
    {
        /**
         * TODO : The reason why there is diverging code below is because V2 and V3 is using different registration objects
         * which results in different containers for V2 and V3 registrations.
         * Once we make V3 use DatabusRegistration, we should be having one call.
         *
         * Note: Couldn't use instanceof for differentiating V2/V3 as V3 Client is not visible here.
         */
       if ( _client.getClass().getSimpleName().equalsIgnoreCase("DatabusHttpClientImpl") )
         processUnifiedRegistration(request);
       else
         processUnifiedRegistrationV3(request);
    }
    else if (category.equals(UNIFIED_TOTAL_KEY))
    {
      processUnifiedTotalStats(_client.getUnifiedClientStatsCollectors(), request);
    }
    else
    {
      success = false;
    }

    return success;
  }

  private void processUnifiedTotalStats(StatsCollectors<UnifiedClientStats> statsCollectors,
                                       DatabusRequest request) throws IOException
  {
    if (null == statsCollectors) return;

    UnifiedClientStats unifiedTotalStats = statsCollectors.getStatsCollector();
    if (null == unifiedTotalStats) return;

    writeJsonObjectToResponse(unifiedTotalStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(unifiedTotalStats, request);
    }
  }

  private void processEventsTotalStats(DbusEventsStatisticsCollector statsCollector,
                                       DatabusRequest request) throws IOException
  {
    if (null == statsCollector) return;

    DbusEventsTotalStats totalStatsMBean = statsCollector.getTotalStats();
    if (null == totalStatsMBean) return;

    writeJsonObjectToResponse(totalStatsMBean, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(totalStatsMBean, request);
    }
  }

  private void processEventsSourcesList(DbusEventsStatisticsCollector statsCollector,
                                        DatabusRequest request) throws IOException
  {
    if (null == statsCollector) return;

    List<Integer> sourcesList = statsCollector.getSources();
    writeJsonObjectToResponse(sourcesList, request);
  }

  private void processEventsSourceStats(DbusEventsStatisticsCollector statsCollector,
                                        String prefix,
                                        DatabusRequest request)
                                        throws IOException, RequestProcessingException
  {
    if (null == statsCollector) return;

    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String sourceIdStr = category.substring(prefix.length());
    int sourceId = -1;
    try
    {
      sourceId = Integer.valueOf(sourceIdStr);
    }
    catch (NumberFormatException nfe)
    {
      throw new InvalidRequestParamValueException(request.getName(), prefix, sourceIdStr);
    }

    DbusEventsTotalStats sourceStats = statsCollector.getSourceStats(sourceId);
    if (null == sourceStats)
    {
      throw new InvalidRequestParamValueException(request.getName(), prefix, sourceIdStr);
    }

    writeJsonObjectToResponse(sourceStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(sourceStats, request);
    }

  }

  private void processEventsPeersList(DbusEventsStatisticsCollector statsCollector,
                                      DatabusRequest request) throws IOException
  {
    if (null == statsCollector) return;

    List<String> clientsList = statsCollector.getPeers();
    writeJsonObjectToResponse(clientsList, request);
  }

  private void processEventsPeerStats(DbusEventsStatisticsCollector statsCollector,
                                      String prefix,
                                      DatabusRequest request)
                                      throws IOException, RequestProcessingException
  {
    if (null == statsCollector) return;

    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String client = category.substring(prefix.length());

    DbusEventsTotalStats clientStats = statsCollector.getPeerStats(client);
    if (null == clientStats)
    {
      throw new InvalidRequestParamValueException(request.getName(), prefix, client);
    }

    writeJsonObjectToResponse(clientStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(clientStats, request);
    }
  }

  private void processOutboundHttpTotalStats(DatabusRequest request) throws IOException
  {
    DbusHttpTotalStats totalStats =  _client.getHttpStatsCollector().getTotalStats();
    if (null == totalStats) return;

    writeJsonObjectToResponse(totalStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(totalStats, request);
    }
  }

  private void processOutboundHttpSourcesList(DatabusRequest request) throws IOException
  {
    List<Integer> sourcesList = _client.getHttpStatsCollector().getSources();
    writeJsonObjectToResponse(sourcesList, request);
  }

  private void processOutboundHttpClientsList(DatabusRequest request) throws IOException
  {
    List<String> clientsList = _client.getHttpStatsCollector().getPeers();
    writeJsonObjectToResponse(clientsList, request);
  }

  private void processOutboundHttpSourceStats(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String sourceIdStr = category.substring(INBOUND_HTTP_SOURCE_PREFIX.length());
    int sourceId = -1;
    try
    {
      sourceId = Integer.valueOf(sourceIdStr);
    }
    catch (NumberFormatException nfe)
    {
      throw new InvalidRequestParamValueException(request.getName(), INBOUND_HTTP_SOURCE_PREFIX, sourceIdStr);
    }

    DbusHttpTotalStats sourceStats = _client.getHttpStatsCollector().getSourceStats(sourceId);
    if (null == sourceStats)
    {
      throw new InvalidRequestParamValueException(request.getName(), INBOUND_HTTP_SOURCE_PREFIX, sourceIdStr);
    }

    writeJsonObjectToResponse(sourceStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(sourceStats, request);
    }
  }

  private void processOutboundHttpClientStats(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String client = category.substring(INBOUND_HTTP_RELAYS_PREFIX.length());

    DbusHttpTotalStats clientStats = _client.getHttpStatsCollector().getPeerStats(client);
    if (null == clientStats)
    {
      throw new InvalidRequestParamValueException(request.getName(), INBOUND_HTTP_RELAYS_PREFIX, client);
    }

    writeJsonObjectToResponse(clientStats, request);

    if (request.getRequestType() == HttpMethod.PUT || request.getRequestType() == HttpMethod.POST)
    {
      enableOrResetStatsMBean(clientStats, request);
    }
  }

  private void processInboundEventsRegistration(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusRegistration reg = findRegistration(request, INBOUND_EVENTS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getRelayEventStats().getTotalStats(), request);
  }

  private void processBootstrapEventsRegistration(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusRegistration reg = findRegistration(request, BOOTSTRAP_EVENTS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getBootstrapEventStats().getTotalStats(), request);
  }

  private void processInboundCallbacksRegistration(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusRegistration reg = findRegistration(request, INBOUND_CALLBACKS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getRelayCallbackStats(), request);
  }

  private void processBootstrapCallbacksRegistration(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusRegistration reg = findRegistration(request, BOOTSTRAP_CALLBACKS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getBootstrapCallbackStats(), request);
  }

  private void processUnifiedRegistration(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusRegistration reg = findRegistration(request, UNIFIED_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getUnifiedClientStats(), request);
  }

  private DatabusRegistration findRegistration(DatabusRequest request, String prefix) throws RequestProcessingException
  {
    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String registrationIdStr = category.substring(prefix.length());
    RegistrationId regId = new RegistrationId(registrationIdStr);

    Collection<DatabusRegistration> regs = _client.getAllRegistrations();

    for (DatabusRegistration r : regs)
    {
      if (regId.equals(r.getRegistrationId()))
        return r;

      if (r instanceof DatabusMultiPartitionRegistration)
      {
        Map<DbusPartitionInfo, DatabusRegistration> childRegs =  ((DatabusMultiPartitionRegistration)r).getPartitionRegs();
        for (Entry<DbusPartitionInfo, DatabusRegistration> e : childRegs.entrySet())
          if ( regId.equals(e.getValue().getRegistrationId()))
            return e.getValue();
      }

    }
    throw new RequestProcessingException("Unable to find registration (" + regId + ") ");
  }

  private void processInboundEventsRegistrationV3(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusV3Registration reg = findV3Registration(request, INBOUND_EVENTS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getRelayEventStats().getTotalStats(), request);
  }

  private void processBootstrapEventsRegistrationV3(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusV3Registration reg = findV3Registration(request, BOOTSTRAP_EVENTS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getBootstrapEventStats().getTotalStats(), request);
  }

  private void processInboundCallbacksRegistrationV3(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusV3Registration reg = findV3Registration(request, INBOUND_CALLBACKS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getRelayCallbackStats(), request);
  }

  private void processBootstrapCallbacksRegistrationV3(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusV3Registration reg = findV3Registration(request, BOOTSTRAP_CALLBACKS_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getBootstrapCallbackStats(), request);
  }

  private void processUnifiedRegistrationV3(DatabusRequest request)
      throws IOException, RequestProcessingException
  {
    DatabusV3Registration reg = findV3Registration(request, UNIFIED_REG_KEY_PREFIX);
    writeJsonObjectToResponse(reg.getUnifiedClientStats(), request);
  }

  private DatabusV3Registration findV3Registration(DatabusRequest request, String prefix)
    throws InvalidRequestParamValueException
  {
    String category = request.getParams().getProperty(DatabusRequest.PATH_PARAM_NAME);
    String registrationIdStr = category.substring(prefix.length());
    DatabusV3Registration reg = _client.getRegistration(new RegistrationId(registrationIdStr));
    if ( null == reg )
    {
        LOG.warn("Invalid registrationId: " + registrationIdStr );
        throw new InvalidRequestParamValueException(request.getName(), prefix, "No data available for this RegistrationId yet" );
    }
    return reg;
  }
}
TOP

Related Classes of com.linkedin.databus.client.request.ClientStatsRequestProcessor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.