private static LoadBalancingDataPublisher getDataPublisher()
      throws AgentException, MalformedURLException, AuthenticationException, TransportException {

    String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain();

    // Get LoadBalancingDataPublisher which has been registered for the tenant.
    LoadBalancingDataPublisher loadBalancingDataPublisher =
        UsageComponent.getDataPublisher(tenantDomain);

    // If a LoadBalancingDataPublisher had not been registered for the tenant.
    if (loadBalancingDataPublisher == null) {

      List<String> receiverGroups =
          org.wso2.carbon.databridge.agent.thrift.util.DataPublisherUtil.getReceiverGroups(
              DataPublisherUtil.getApiManagerAnalyticsConfiguration().getBamServerUrlGroups());

      String serverUser =
          DataPublisherUtil.getApiManagerAnalyticsConfiguration().getBamServerUser();
      String serverPassword =
          DataPublisherUtil.getApiManagerAnalyticsConfiguration().getBamServerPassword();
      List<ReceiverGroup> allReceiverGroups = new ArrayList<ReceiverGroup>();

      for (String receiverGroupString : receiverGroups) {
        String[] serverURLs = receiverGroupString.split(",");
        List<DataPublisherHolder> dataPublisherHolders = new ArrayList<DataPublisherHolder>();

        for (int i = 0; i < serverURLs.length; i++) {
          String serverURL = serverURLs[i];
          DataPublisherHolder dataPublisherHolder =
              new DataPublisherHolder(null, serverURL, serverUser, serverPassword);
          dataPublisherHolders.add(dataPublisherHolder);
        }

        ReceiverGroup receiverGroup = new ReceiverGroup((ArrayList) dataPublisherHolders);
        allReceiverGroups.add(receiverGroup);
      }

      // Create new LoadBalancingDataPublisher for the tenant.
      loadBalancingDataPublisher = new LoadBalancingDataPublisher((ArrayList) allReceiverGroups);
      try {
        // Add created LoadBalancingDataPublisher.
        UsageComponent.addDataPublisher(tenantDomain, loadBalancingDataPublisher);
      } catch (DataPublisherAlreadyExistsException e) {
        log.warn(
            "Attempting to register a data publisher for the tenant "
                + tenantDomain
                + " when one already exists. Returning existing data publisher");
        return UsageComponent.getDataPublisher(tenantDomain);
      }
    }

    return loadBalancingDataPublisher;
  }
public class APIMgtFaultHandler extends AbstractMediator {

  private boolean enabled = UsageComponent.getApiMgtConfigReaderService().isEnabled();

  private volatile APIMgtUsageDataPublisher publisher;

  private String publisherClass = UsageComponent.getApiMgtConfigReaderService().getPublisherClass();

  public APIMgtFaultHandler() {

    if (!enabled) {
      return;
    }

    if (publisher == null) {
      synchronized (this) {
        if (publisher == null) {
          try {
            log.debug("Instantiating Data Publisher");
            publisher = (APIMgtUsageDataPublisher) Class.forName(publisherClass).newInstance();
            publisher.init();
          } catch (ClassNotFoundException e) {
            log.error("Class not found " + publisherClass);
          } catch (InstantiationException e) {
            log.error("Error instantiating " + publisherClass);
          } catch (IllegalAccessException e) {
            log.error("Illegal access to " + publisherClass);
          }
        }
      }
    }
  }

  public boolean mediate(MessageContext messageContext) {

    try {
      if (!enabled) {
        return true;
      }
      long requestTime =
          ((Long) messageContext.getProperty(APIMgtUsagePublisherConstants.REQUEST_TIME))
              .longValue();

      FaultPublisherDTO faultPublisherDTO = new FaultPublisherDTO();
      faultPublisherDTO.setConsumerKey(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.CONSUMER_KEY));
      faultPublisherDTO.setContext(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.CONTEXT));
      faultPublisherDTO.setApi_version(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.API_VERSION));
      faultPublisherDTO.setApi(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.API));
      faultPublisherDTO.setResource(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.RESOURCE));
      faultPublisherDTO.setMethod(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.HTTP_METHOD));
      faultPublisherDTO.setVersion(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.VERSION));
      faultPublisherDTO.setErrorCode(
          String.valueOf(messageContext.getProperty(SynapseConstants.ERROR_CODE)));
      faultPublisherDTO.setErrorMessage(
          (String) messageContext.getProperty(SynapseConstants.ERROR_MESSAGE));
      faultPublisherDTO.setRequestTime(requestTime);
      faultPublisherDTO.setUsername(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.USER_ID));
      faultPublisherDTO.setTenantDomain(
          MultitenantUtils.getTenantDomain(faultPublisherDTO.getUsername()));
      faultPublisherDTO.setHostName(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.HOST_NAME));
      faultPublisherDTO.setApiPublisher(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.API_PUBLISHER));
      faultPublisherDTO.setApplicationName(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.APPLICATION_NAME));
      faultPublisherDTO.setApplicationId(
          (String) messageContext.getProperty(APIMgtUsagePublisherConstants.APPLICATION_ID));

      publisher.publishEvent(faultPublisherDTO);

    } catch (Throwable e) {
      log.error("Cannot publish event. " + e.getMessage(), e);
    }
    return true; // Should never stop the message flow
  }
}