Package com.fasterxml.clustermate.servlet

Source Code of com.fasterxml.clustermate.servlet.StoreEntryInfoServlet

package com.fasterxml.clustermate.servlet;

import java.io.IOException;

import com.codahale.metrics.Timer.Context;
import com.fasterxml.jackson.databind.ObjectWriter;
import com.fasterxml.storemate.store.Storable;
import com.fasterxml.storemate.store.util.OperationDiagnostics;
import com.fasterxml.clustermate.api.EntryKey;
import com.fasterxml.clustermate.api.EntryKeyConverter;
import com.fasterxml.clustermate.service.SharedServiceStuff;
import com.fasterxml.clustermate.service.cfg.ServiceConfig;
import com.fasterxml.clustermate.service.cluster.ClusterViewByServer;
import com.fasterxml.clustermate.service.metrics.AllOperationMetrics;
import com.fasterxml.clustermate.service.metrics.ExternalOperationMetrics;
import com.fasterxml.clustermate.service.metrics.OperationMetrics;
import com.fasterxml.clustermate.service.store.StoreHandler;
import com.fasterxml.clustermate.service.store.StoredEntry;
import com.fasterxml.clustermate.service.store.StoredEntryConverter;

/**
* Servlet that handles access to per-entry metadata.
*/
@SuppressWarnings("serial")
public class StoreEntryInfoServlet<K extends EntryKey, E extends StoredEntry<K>>
    extends ServletWithMetricsBase
{
    /*
    /**********************************************************************
    /* Helper objects
    /**********************************************************************
     */

    protected final SharedServiceStuff _stuff;
   
    protected final StoreHandler<K,E,?> _storeHandler;

    protected final ObjectWriter _jsonWriter;

    protected final EntryKeyConverter<K> _keyConverter;

    protected final StoredEntryConverter<K,E,?> _entryConverter;

    /*
    /**********************************************************************
    /* Metrics info
    /**********************************************************************
     */

    protected final OperationMetrics _getMetrics;

    /*
    /**********************************************************************
    /* Life-cycle
    /**********************************************************************
     */

    public StoreEntryInfoServlet(SharedServiceStuff stuff, ClusterViewByServer clusterView,
            StoreHandler<K,E,?> storeHandler)
    {
        this(stuff, clusterView, storeHandler, false);
    }

    protected StoreEntryInfoServlet(SharedServiceStuff stuff, ClusterViewByServer clusterView,
            StoreHandler<K,E,?> storeHandler, boolean handleRouting)
    {
        // null -> use servlet path base as-is
        super(stuff, clusterView, null);
        _stuff = stuff;
        _storeHandler = storeHandler;
        _jsonWriter = stuff.jsonWriter();
        _entryConverter = stuff.getEntryConverter();
        _keyConverter = _entryConverter.keyConverter();
        ServiceConfig serviceConfig = stuff.getServiceConfig();
        if (serviceConfig.metricsEnabled) {
            _getMetrics = OperationMetrics.forEntityOperation(serviceConfig, "entryInfoGet");
        } else {
            _getMetrics = null;
        }
    }

    protected StoreEntryInfoServlet(StoreEntryInfoServlet<K,E> base,
            boolean copyMetrics)
    {
        super(base._stuff, base._clusterView, null);
        _stuff = base._stuff;
        _storeHandler = base._storeHandler;
        _jsonWriter = base._jsonWriter;
        _entryConverter = base._entryConverter;
        _keyConverter = base._keyConverter;
        if (copyMetrics) {
            _getMetrics = base._getMetrics;
        } else {
            _getMetrics = null;
        }
    }

    // TODO, maybe?
    /*
    public ServletBase createRoutingServlet() {
        return new RoutingEntryInfoServlet<K,E>(this);
    }
    */

    /*
    /**********************************************************************
    /* Access to metrics (AllOperationMetrics.Provider impl)
    /**********************************************************************
     */

    @Override
    public void fillOperationMetrics(AllOperationMetrics metrics)
    {
        metrics.GET = ExternalOperationMetrics.create(_getMetrics);
        _storeHandler.augmentOperationMetrics(metrics);
    }
   
    /*
    /**********************************************************************
    /* Default implementations for key handling
    /**********************************************************************
     */

    protected K _findKey(ServletServiceRequest request, ServletServiceResponse response)
    {
        return _keyConverter.extractFromPath(request);
    }
   
    /*
    /**********************************************************************
    /* Main Verb handlers
    /**********************************************************************
     */

    @Override
    public void handleGet(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats) throws IOException
    {
        final OperationMetrics metrics = _getMetrics;
        Context timer = (metrics == null) ? null : metrics.start();
        try {
            K key = _findKey(request, response);
            if (key != null) { // null means trouble; response has all we need
                response = _handleGet(request, response, stats, key);
            }
            response.writeOut(_jsonWriter);
        } finally {
            if (metrics != null) {
                 metrics.finish(timer, stats);
            }
        }
    }

    // Do we even need to support HEAD? Might as well, I guess
    @Override
    public void handleHead(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats) throws IOException
    {
        K key = _findKey(request, response);
        if (key != null) {
            response = _handleHead(request, response, stats, key);
        }
        // note: should be enough to just add headers; no content to write
    }

    /*
    /**********************************************************************
    /* Handlers for actual operations, overridable
    /**********************************************************************
     */

    protected ServletServiceResponse _handleGet(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats, K key)
        throws IOException
    {
        Storable entry = _storeHandler.findRawEntryForInfo(key, stats);
        if (entry == null) {
            return response.notFound();
        }
        response = response.setContentTypeJson()
                .ok(_entryConverter.itemInfoFromStorable(entry));
        _addStdHeaders(response);
        return response;
    }

    protected ServletServiceResponse _handleHead(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats, K key)
        throws IOException
    {
        Storable entry = _storeHandler.findRawEntryForInfo(key, stats);
        if (entry == null) {
            return response.notFound();
        }
        // What kind of info, if any, should we return? Content-length would be possible,
        // but misleading/inaccurate, since our payload is JSON, not stored entry
        response = response.ok();
        _addStdHeaders(response);
        return response;
    }
}
TOP

Related Classes of com.fasterxml.clustermate.servlet.StoreEntryInfoServlet

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.