All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.endoscope.cdiui.StatsDataController Maven / Gradle / Ivy

There is a newer version: 1.0.18
Show newest version
package com.github.endoscope.cdiui;

import com.github.endoscope.Endoscope;
import com.github.endoscope.core.Stat;
import com.github.endoscope.core.Stats;
import com.github.endoscope.storage.SearchableStatsStorage;
import com.github.endoscope.storage.StatDetails;
import com.github.endoscope.storage.StatHistory;
import com.github.endoscope.util.JsonUtil;
import org.slf4j.Logger;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.CacheControl;
import javax.ws.rs.core.Response;
import java.util.Date;

import static org.slf4j.LoggerFactory.getLogger;

@Path("/endoscope")
public class StatsDataController {
    private static final Logger log = getLogger(StatsDataController.class);

    private JsonUtil jsonUtil = new JsonUtil();

    protected Response noCacheResponse( Object entity ) {
        CacheControl cc = new CacheControl();
        cc.setNoCache( true );
        cc.setMaxAge( -1 );
        cc.setMustRevalidate( true );

        return Response.ok( entity ).cacheControl( cc ).build();
    }

    @GET
    @Path("/data/top")
    @Produces("application/json")
    public Response top(@QueryParam("from") String fromS, @QueryParam("to") String toS, @QueryParam("past") String pastS,
                        @QueryParam("reset") boolean reset) {
        Long from = toLong(fromS), to = toLong(toS), past = toLong(pastS);

        if( reset ){
            log.info("Reseting current stats");
            Endoscope.resetStats();
        }

        Stats stats = topLevelForRange(new Range(from, to, past));
        return noCacheResponse(jsonUtil.toJson(stats.getMap()));
    }

    private Long toLong(String value){
        if( value == null || value.trim().length() == 0 ){
            return null;
        }
        return Long.valueOf(value);
    }

    @GET
    @Path("/data/details")
    @Produces("application/json")
    public Response details(@QueryParam("id") String id,
                            @QueryParam("from") String fromS, @QueryParam("to") String toS, @QueryParam("past") String pastS){
        Long from = toLong(fromS), to = toLong(toS), past = toLong(pastS);
        StatDetails child = detailsForRange(id, new Range(from, to, past));
        return noCacheResponse(jsonUtil.toJson(child));
    }

    private static class Range {
        public Range(Long from, Long to, Long past){
            if( past != null ){
                if( past > 0 ){
                    toDate = new Date();
                    fromDate = new Date(toDate.getTime() - past);
                }
            } else {
                if( from != null ){
                    fromDate = new Date(from);

                    //to requires from
                    if( to != null ){
                        toDate = new Date(to);
                        includeCurrent = false;
                    } else {
                        toDate = new Date();
                    }
                }
            }
        }

        Date fromDate = null;
        Date toDate = null;
        boolean includeCurrent = true;
    }

    private Stats topLevelForRange(Range range) {
        Stats result;
        if( canSearch(range) ){
            result = getSearchableStatsStorage().topLevel(range.fromDate, range.toDate);
            if( range.includeCurrent ){
                Stats current = topLevelInMemory();
                result.merge(current, false);
            }
        } else{
            result = topLevelInMemory();
        }
        return result;
    }

    private StatDetails detailsForRange(String id, Range range) {
        StatDetails result;
        if( canSearch(range) ){
            result = getSearchableStatsStorage().stat(id, range.fromDate, range.toDate);
            if( range.includeCurrent ){
                StatDetails current = detailsInMemory(id);
                if( current != null ){
                    //we don't want to merge not set stats as it would reset min value to 0
                    result.getMerged().merge(current.getMerged(), true);
                    result.getHistogram().addAll(current.getHistogram());
                }
            }
        } else {
            result = detailsInMemory(id);
        }
        return (result != null) ? result : new StatDetails(id, Stat.EMPTY_STAT);
    }

    private boolean canSearch(Range range){
        return range.fromDate != null && range.toDate != null
                && Endoscope.getStatsStorage() != null;
    }

    private Stats topLevelInMemory() {
        return Endoscope.processStats(stats -> stats.deepCopy(false) );
    }

    private StatDetails detailsInMemory(String id) {
        return Endoscope.processStats(stats -> {
            Stat s = stats.getMap().get(id);
            if( s == null ){//might happen when stats get saved and/or reset in the mean time
                return null;
            }
            StatDetails result = new StatDetails();
            s = s.deepCopy();
            result.setMerged(s);
            result.getHistogram().add(
                new StatHistory(s, stats.getStartDate(), new Date())
            );
            return result;
        });
    }

    private SearchableStatsStorage getSearchableStatsStorage() {
        SearchableStatsStorage storage;
        try{
            storage = (SearchableStatsStorage) Endoscope.getStatsStorage();
            if( storage == null ){
                throw new RuntimeException("Storage not supported");
            }
        }catch(ClassCastException e){
            throw new RuntimeException("Range search is not supported");
        }
        return storage;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy