ch.icclab.cyclops.services.iaas.openstack.resource.impl.ResourceUsage.java Source code

Java tutorial

Introduction

Here is the source code for ch.icclab.cyclops.services.iaas.openstack.resource.impl.ResourceUsage.java

Source

/*
 * Copyright (c) 2015. Zuercher Hochschule fuer Angewandte Wissenschaften
 *  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.
 */

package ch.icclab.cyclops.services.iaas.openstack.resource.impl;

import ch.icclab.cyclops.services.iaas.openstack.model.ResourceUsageResponse;
import ch.icclab.cyclops.services.iaas.openstack.model.TSDBData;
import ch.icclab.cyclops.support.database.influxdb.client.InfluxDBClient;
import ch.icclab.cyclops.util.APICallCounter;
import ch.icclab.cyclops.util.DateTimeUtil;
import ch.icclab.cyclops.util.Load;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.json.JSONArray;
import org.restlet.engine.local.Entity;
import org.restlet.ext.json.JsonRepresentation;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.ServerResource;

import java.util.ArrayList;
import java.util.HashMap;

/**
 * This Class is going to ask to the DB for the Usage Data and give back the CDR.<p/>
 * <p>
 * Author: Srikanta
 * Created on: 01-Apr-15
 * Description:
 */
public class ResourceUsage extends ServerResource {
    final static Logger logger = LogManager.getLogger(ResourceUsage.class.getName());
    private String resourceId;
    private String endpoint = "/usage/resources";
    private APICallCounter counter = APICallCounter.getInstance();

    public void doInit() {
        resourceId = (String) getRequestAttributes().get("resourceid");
    }

    @Get
    public Representation getResourceUsage(Entity entity) {
        counter.increment(endpoint);
        logger.trace("BEGIN Representation getResourceUsage(Entity entity)");
        String query = null;
        String jsonStr;
        JsonRepresentation responseJson = null;
        TSDBData[] tsdbData;
        InfluxDBClient dbClient = new InfluxDBClient();
        DateTimeUtil dateUtil = new DateTimeUtil();
        ResourceUsageResponse resourceUsageResponse = new ResourceUsageResponse();
        ArrayList<ResourceUsageResponse> resourcesArray = new ArrayList<ResourceUsageResponse>();
        HashMap time = new HashMap();
        ObjectMapper mapper = new ObjectMapper();
        boolean cumulative = false, gauge = false, sum = false;

        String fromDate = getQueryValue("from");
        String toDate = getQueryValue("to");
        fromDate = dateUtil.formatDate(fromDate);
        toDate = dateUtil.formatDate(toDate);
        time.put("from", fromDate);
        time.put("to", toDate);

        if (Load.getOpenStackCumulativeMeterList().contains(resourceId)) {
            query = "SELECT usage FROM \"" + resourceId + "\" WHERE time > '" + fromDate + "' AND time < '" + toDate
                    + "' GROUP BY userid";
            sum = true;
        } else if (Load.getOpenStackGaugeMeterList().contains(resourceId)) {
            query = "SELECT MEAN(avg) FROM \"" + resourceId + "\" WHERE time > '" + fromDate + "' AND time < '"
                    + toDate + "' GROUP BY userid";
        } else if (Load.getExternalMeterList().contains(resourceId)) {
            //query = "SELECT SUM(usage) FROM \"" + resourceId + "\" WHERE time > '" + fromDate + "' AND time < '" + toDate + "' GROUP BY userid";
            query = "SELECT usage FROM \"" + resourceId + "\" WHERE time > '" + fromDate + "' AND time < '" + toDate
                    + "' GROUP BY userid";
            sum = true;
        } else {
            // Fall back response TODO
            logger.debug("DEBUG Representation getResourceUsage(Entity entity): No Meter List specified");
        }
        tsdbData = dbClient.getCDRData(query);
        if (sum)
            tsdbData = sumExternalMeterData(tsdbData);
        if (tsdbData != null) {
            for (int i = 0; i < tsdbData.length; i++) {
                //Create a new ResourceUsageResponse
                resourceUsageResponse = new ResourceUsageResponse();
                resourceUsageResponse.setResourceid(resourceId);
                resourceUsageResponse.setTime(time);
                //Add the ResourceUsageResponse to the resourcesArray (initially empty ArrayList)
                resourcesArray.add(resourceUsageResponse);
                resourcesArray.get(i).setColumn(tsdbData[i].getColumns());
                resourcesArray.get(i).setUsage(tsdbData[i].getPoints());
                resourcesArray.get(i).setTags(tsdbData[i].getTags());

            }
        } else {
            logger.debug("DEBUG Representation getResourceUsage(Entity entity): tsdbData is null");
            //TODO: 2 field constructor to set null columns and usage.
            resourceUsageResponse.setResourceid(resourceId);
            resourceUsageResponse.setTime(time);
            resourceUsageResponse.setColumn(null);
            resourceUsageResponse.setUsage(null);
        }

        try {
            jsonStr = mapper.writeValueAsString(resourcesArray);
            responseJson = new JsonRepresentation(jsonStr);
        } catch (JsonProcessingException e) {
            logger.error("EXCEPTION JSONPROCESSINGEXCEPTION Representation getResourceUsage(Entity entity)");
            e.printStackTrace();
        }
        return responseJson;
    }

    /**
     * This method sums all the values of the gotten points from the external meter data and sums their values.
     *<br/>
     * Pseudo Code:
     * <br/>
     * 1. Get the column indexes <br/>
     * 2. Aggregate all the points usage<br/>
     * 3. Add the last point time with the aggregation of usages and return it.
     *
     * @param tsdbData
     * @return
     */
    private TSDBData[] sumExternalMeterData(TSDBData[] tsdbData) {
        TSDBData[] result = tsdbData;
        for (int i = 0; i < tsdbData.length; i++) {
            ArrayList<Object> finalPoint = new ArrayList<Object>();
            int usage = 0;
            int usageIndex = tsdbData[i].getColumns().indexOf("usage");
            int timeIndex = tsdbData[i].getColumns().indexOf("time");

            for (int o = 0; o < tsdbData[i].getPoints().size(); o++) {
                usage = usage + Integer.parseInt((String) tsdbData[i].getPoints().get(o).get(usageIndex));
                if (o == tsdbData[i].getPoints().size() - 1) {
                    String time = (String) tsdbData[i].getPoints().get(o).get(timeIndex);
                    finalPoint.add(timeIndex, time);
                    finalPoint.add(usageIndex, String.valueOf(usage));
                }
            }
            result[i].getPoints().clear();
            result[i].getPoints().add(0, finalPoint);
        }
        return result;
    }

}