com.cisco.oss.foundation.http.server.MonitoringFilter.java Source code

Java tutorial

Introduction

Here is the source code for com.cisco.oss.foundation.http.server.MonitoringFilter.java

Source

/*
 * Copyright 2015 Cisco Systems, Inc.
 *
 *  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.
 */

package com.cisco.oss.foundation.http.server;

import com.cisco.oss.foundation.configuration.ConfigUtil;
import com.cisco.oss.foundation.configuration.ConfigurationFactory;
import com.cisco.oss.foundation.monitoring.CommunicationInfo;
import com.cisco.oss.foundation.monitoring.MonitoringAgentFactory;
import com.cisco.oss.foundation.monitoring.services.ServiceDetails;
import com.cisco.oss.foundation.string.utils.BoyerMoore;
import org.apache.commons.lang3.tuple.Pair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Component
@Order(40)
public class MonitoringFilter extends AbstractInfraHttpFilter {

    private final static Logger LOGGER = LoggerFactory.getLogger(MonitoringFilter.class);

    private ServiceDetails serviceDetails;
    private HttpThreadPool threadPool = null;
    private String description;
    private int port;
    private boolean isMonitoringWithWrappers = false;
    private boolean uniqueUriMonitoringEnabled = false;
    private List<BoyerMoore> boyers = new ArrayList<BoyerMoore>();
    private boolean isRegistered = false;

    public MonitoringFilter() {
        super();
        description = ConfigurationFactory.getConfiguration().getString(serviceName + ".http.serviceDescription",
                "DEFAULT_DESCRIPTION");
        port = ConfigurationFactory.getConfiguration().getInt(serviceName + ".http.port", 8080);
        serviceDetails = new ServiceDetails(description, serviceName, "HTTP", port);
        uniqueUriMonitoringEnabled = ConfigurationFactory.getConfiguration()
                .getBoolean(serviceName + ".http.monitoringFilter.uniqueUriMonitoringEnabled", false);
        if (!uniqueUriMonitoringEnabled) {
            populateBoyersList();
        }
        regiterMonitoring();
    }

    private void regiterMonitoring() {
        if (!isRegistered && getConfigValue(enabledKey, isEnabledByDefault())) {
            MonitoringAgentFactory.getInstance().register();
            isRegistered = true;
        }

    }

    public MonitoringFilter(String serviceName, HttpThreadPool threadPool) {
        super(serviceName);
        this.threadPool = threadPool;
        description = ConfigurationFactory.getConfiguration().getString(serviceName + ".http.serviceDescription",
                "DEFAULT_DESCRIPTION");
        port = ConfigurationFactory.getConfiguration().getInt(serviceName + ".http.port", 8080);
        serviceDetails = new ServiceDetails(description, serviceName, "HTTP", port);
        uniqueUriMonitoringEnabled = ConfigurationFactory.getConfiguration()
                .getBoolean(serviceName + ".http.monitoringFilter.uniqueUriMonitoringEnabled", false);
        if (!uniqueUriMonitoringEnabled) {
            populateBoyersList();
        }
        regiterMonitoring();
    }

    private void populateBoyersList() {
        Map<String, String> parseSimpleArrayAsMap = ConfigUtil
                .parseSimpleArrayAsMap(serviceName + ".http.monitoringFilter.baseUri");
        List<String> keys = new ArrayList<String>(parseSimpleArrayAsMap.keySet());
        //      Collections.sort(keys);
        Collections.sort(keys, new Comparator<String>() {
            // Overriding the compare method to sort the age
            public int compare(String str1, String str2) {
                return Integer.parseInt(str1) - Integer.parseInt(str2);
            }
        });

        for (String key : keys) {
            String baseUri = parseSimpleArrayAsMap.get(key);
            boyers.add(new BoyerMoore(baseUri));
        }

    }

    @Override
    public void doFilterImpl(final ServletRequest request, final ServletResponse response, final FilterChain chain)
            throws IOException, ServletException {

        regiterMonitoring();

        final long startTime = System.currentTimeMillis();
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;
        String tempMethodName = httpServletRequest.getMethod();
        if (uniqueUriMonitoringEnabled) {
            tempMethodName += ":" + httpServletRequest.getRequestURI();
        }

        boolean reportToMonitoring = true;

        try {
            LOGGER.trace("Monitoring filter: Request processing started at: {}", startTime);

            //         methodName = httpServletRequest.getMethod() + ":" + httpServletRequest.getRequestURI().toString();
            tempMethodName = updateMethodName(httpServletRequest, tempMethodName);

            LOGGER.trace("transaction method name is: {}", tempMethodName);

            CommunicationInfo.getCommunicationInfo().transactionStarted(serviceDetails, tempMethodName,
                    threadPool != null ? threadPool.getThreads() : -1);

        } catch (Exception e) {
            LOGGER.error("can't report monitoring data as it has failed on:" + e);
            reportToMonitoring = false;
        }
        final String methodName = tempMethodName;

        try {
            chain.doFilter(httpServletRequest, httpServletResponse);

            if (request.isAsyncStarted()) {

                AsyncContext async = request.getAsyncContext();
                async.addListener(new AsyncListener() {
                    @Override
                    public void onComplete(AsyncEvent event) throws IOException {
                        final long endTime = System.currentTimeMillis();
                        final int processingTime = (int) (endTime - startTime);
                        LOGGER.debug("Processing time: {} milliseconds", processingTime);
                    }

                    @Override
                    public void onTimeout(AsyncEvent event) throws IOException {

                    }

                    @Override
                    public void onError(AsyncEvent event) throws IOException {
                        Throwable throwable = event.getThrowable();
                        if (throwable != null) {
                            CommunicationInfo.getCommunicationInfo().transactionFinished(serviceDetails, methodName,
                                    true, throwable.toString());
                        }
                    }

                    @Override
                    public void onStartAsync(AsyncEvent event) throws IOException {

                    }
                });

            } else {
                final long endTime = System.currentTimeMillis();
                final int processingTime = (int) (endTime - startTime);
                LOGGER.debug("Processing time: {} milliseconds", processingTime);
            }

        } catch (Exception e) {
            CommunicationInfo.getCommunicationInfo().transactionFinished(serviceDetails, methodName, true,
                    e.toString());
            throw e;
        }

        if (reportToMonitoring) {
            try {

                int status = httpServletResponse.getStatus();

                if (status >= 400) {
                    CommunicationInfo.getCommunicationInfo().transactionFinished(serviceDetails, methodName, true,
                            httpServletResponse.getStatus() + "");

                } else {

                    CommunicationInfo.getCommunicationInfo().transactionFinished(serviceDetails, methodName, false,
                            "");
                }
            } catch (Exception e) {
                LOGGER.error("can't report monitoring data as it has failed on:" + e);
            }
        }

    }

    protected String updateMethodName(final HttpServletRequest httpServletRequest, String defaultMethodName) {
        if (!uniqueUriMonitoringEnabled && !boyers.isEmpty()) {
            String uri = httpServletRequest.getRequestURI();
            for (BoyerMoore boyerMoore : boyers) {
                int match = boyerMoore.search(uri);
                if (match >= 0) {
                    return defaultMethodName + ":" + boyerMoore.getPattern();
                }
            }

        }
        return defaultMethodName;
    }

    protected Pair<Boolean, String> chcekResponseStatus(final HttpServletResponse httpServletResponse) {
        return Pair.of(false, "");
    }

    @Override
    protected String getKillSwitchFlag() {
        return "http.monitoringFilter.isEnabled";
    }

    @Override
    protected boolean isEnabledByDefault() {
        return true;
    }

}