Java tutorial
/* * 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.usecases.mcn.impl; import ch.icclab.cyclops.load.Loader; import ch.icclab.cyclops.load.model.InfluxDBSettings; import ch.icclab.cyclops.services.iaas.openstack.model.Response; import ch.icclab.cyclops.services.iaas.openstack.model.TSDBData; import ch.icclab.cyclops.services.iaas.openstack.resource.interfc.EventProcessingResource; 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.JSONUtil; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.influxdb.InfluxDB; import org.influxdb.InfluxDBFactory; import org.influxdb.dto.Point; import org.joda.time.LocalDateTime; import org.restlet.representation.Representation; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.*; public class MCNResource extends ServerResource implements EventProcessingResource { final static Logger logger = LogManager.getLogger(MCNResource.class.getName()); InfluxDBSettings settings = Loader.getSettings().getInfluxDBSettings(); private InfluxDB influxDB = InfluxDBFactory.connect(settings.getInfluxDBURL(), settings.getInfluxDBUsername(), settings.getInfluxDBPassword()); String dbname; private String endpoint = "/mcn/refresh"; private APICallCounter counter = APICallCounter.getInstance(); /** * This method reads all events in the polling frame, processes them and stores the UDRs in InfluxDB. * * @return stores events in UDRs */ @Get public Representation processEvents() { counter.increment(endpoint); TSDBData result = null; Representation jsonOutput = null; JSONUtil jutil = new JSONUtil(); InfluxDBClient dbClient = new InfluxDBClient(); TSDBData[] tsdbData = null; String fromDate = ""; try { fromDate = getQueryValue("from"); } catch (NullPointerException ex) { fromDate = ""; } String parameterQuery = ""; if (fromDate == null) { fromDate = ""; } if (fromDate.equals("")) { parameterQuery = "SELECT * FROM events"; } else { fromDate = fromDate.replaceAll("\"", ""); parameterQuery = "SELECT * FROM events WHERE time >=\"" + fromDate + "\""; } //Load all events dbname = Loader.getSettings().getMcnSettings().getMCNDBEventsName(); tsdbData = dbClient.query(parameterQuery, dbname); //Store clientIDs and instance IDs in map HashMap<String, ArrayList<String>> clientInstanceMap = getInstanceIdsPerClientId(tsdbData); //Save lastevent to InfluxDB. Manu: not saving anything //result = captureLastEvent(clientInstanceMap, dbClient); //Creates UDR records createUDRRecords(clientInstanceMap); return jsonOutput; } private void createUDRRecords(HashMap<String, ArrayList<String>> clientInstanceMap) { McnUsageDataRecordResource udrClient = new McnUsageDataRecordResource(); Iterator it = clientInstanceMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry pair = (Map.Entry) it.next(); String clientId = pair.getKey().toString(); ArrayList<String> instanceIds = (ArrayList<String>) pair.getValue(); for (String instanceId : instanceIds) { udrClient.generateUDR(clientId, instanceId); } System.out.println(pair.getKey() + " = " + pair.getValue()); it.remove(); } } /** * Logs TSDBData arrays * * @param tsdbData */ private void logProcessedData(TSDBData[] tsdbData) { JSONUtil jutil = new JSONUtil(); try { String data = jutil.toJson(tsdbData).getText(); logger.trace("DATA Representation processEvents(): data=" + data); } catch (IOException e) { logger.error("EXCEPTION IOEXCEPTION Representation processEvents()"); e.printStackTrace(); } } /** * Gets last event of clientID/instanceID mappings and returns ArrayList of last events. * * @param clientInstanceMap * @param dbClient */ private TSDBData captureLastEvent(HashMap<String, ArrayList<String>> clientInstanceMap, InfluxDBClient dbClient) { logger.debug("Attempting to get the Last Event for the customer: "); ArrayList<TSDBData> lastEvents = new ArrayList<TSDBData>(); Iterator it = clientInstanceMap.entrySet().iterator(); while (it.hasNext()) { Map.Entry pair = (Map.Entry) it.next(); String clientId = pair.getKey().toString(); ArrayList<String> instances = (ArrayList<String>) pair.getValue(); for (String instance : instances) { String queryString = "SELECT * FROM events WHERE clientid='" + clientId + "' AND instanceid='" + instance + "' ORDER BY time DESC LIMIT 1"; logger.trace("private void captureLastEvent(...): query=" + queryString); TSDBData[] lastEvent = dbClient.query(queryString); //sends the event to array lastEvents.add(lastEvent[0]); } it.remove(); // avoids a ConcurrentModificationException } return lastEvents.get(0); } /** * Gets last event before Date. * * @param clientId * @param instanceID * @param date * @return */ public TSDBData captureLastEventBeforeDate(String clientId, String instanceID, long date) {// Date date){ DateTimeUtil util = new DateTimeUtil(); InfluxDBClient dbClient = new InfluxDBClient(); dbname = Loader.getSettings().getMcnSettings().getMCNDBEventsName(); String parameterQuery = "SELECT * FROM events WHERE clientId='" + clientId + "' AND instanceId='" + instanceID + "' AND time<='" + date + "' ORDER BY time DESC LIMIT 1"; TSDBData[] tsdbData = dbClient.query(parameterQuery, dbname); logger.debug("Last Event: " + tsdbData[0].toString()); return tsdbData[0]; } /** * Gets last event of all events after date * * @param clientId * @param instanceID * @param date * @return */ public TSDBData captureLastEventAfterDate(String clientId, String instanceID, Date date) { InfluxDBClient dbClient = new InfluxDBClient(); dbname = Loader.getSettings().getMcnSettings().getMCNDBEventsName(); String parameterQuery = "SELECT * FROM events WHERE clientId='" + clientId + "' AND instanceId='" + instanceID + "' AND time>='" + date + "' ORDER BY time DESC LIMIT 1"; TSDBData[] tsdbData = dbClient.query(parameterQuery, dbname); return tsdbData[0]; } public TSDBData captureEventsAfterDate(String clientId, String instanceID, Date date) { ArrayList<TSDBData> result = new ArrayList<TSDBData>(); InfluxDBClient dbClient = new InfluxDBClient(); dbname = Loader.getSettings().getMcnSettings().getMCNDBEventsName(); String parameterQuery = "SELECT * FROM events WHERE clientId='" + clientId + "' AND instanceId='" + instanceID + "' AND time>='" + date + "' ORDER BY time DESC"; TSDBData[] tsdbData = dbClient.query(parameterQuery, dbname); // for(int i = 0; i<tsdbData.length; i++){ // result.add(tsdbData[i]); // } return tsdbData[0]; } /** * This method creates the response message of the API call * * @return */ //TODO: remove method private Response constructResponse() { logger.trace("BEGIN constructResponse(TSDBData data)"); Response responseObj = new Response(); LocalDateTime currentDateTime = new LocalDateTime(); responseObj.setTimestamp(currentDateTime.toDateTime().toString()); responseObj.setStatus("Success"); responseObj.setMessage("Event Data retrieved."); logger.trace("BEGIN constructResponse(TSDBData data)"); return responseObj; } /** * This method takes the POJOobject that contains all events, extracts all clientIDs * and saves it to an ArrayList. * * @param tsdbData * @return */ private ArrayList<String> getClientIds(TSDBData[] tsdbData) { logger.trace("BEGIN ArrayList<String> getClientIds(TSDBData[] tsdbData)"); ArrayList<String> result = new ArrayList<String>(); for (TSDBData obj : tsdbData) { ArrayList<String> columns = obj.getColumns(); ArrayList<ArrayList<Object>> points = obj.getPoints(); int clientidIndex = -1; for (int i = 0; i < columns.size(); i++) { if (columns.get(i).equals("clientid")) clientidIndex = i; } for (int i = 0; i < points.size(); i++) { String clientId = points.get(i).get(clientidIndex).toString(); if (!(result.contains(clientId))) { result.add(clientId); } } } logger.trace("END ArrayList<String> getClientIds(TSDBData[] tsdbData)"); return result; } /** * This method takes the POJOobject that contains all events, extracts all clientIDs * and maps instanceIds to them which are saved to a HashMap. * * @param tsdbData * @return */ private HashMap<String, ArrayList<String>> getInstanceIdsPerClientId(TSDBData[] tsdbData) { logger.trace("BEGIN HashMap<String,ArrayList<String>> getInstanceIdsPerClientId(TSDBData[] tsdbData)"); HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>(); for (TSDBData obj : tsdbData) { ArrayList<String> columns = obj.getColumns(); ArrayList<ArrayList<Object>> points = obj.getPoints(); int clientidIndex = -1; int instanceidIndex = -1; for (int i = 0; i < columns.size(); i++) { if (columns.get(i).equals("clientid")) clientidIndex = i; else if (columns.get(i).equals("instanceid")) instanceidIndex = i; } for (int i = 0; i < points.size(); i++) { String clientId = points.get(i).get(clientidIndex).toString(); String InstanceId = points.get(i).get(instanceidIndex).toString(); if (!(map.containsKey(clientId))) { map.put(clientId, new ArrayList<String>()); if (!(map.get(clientId).contains(InstanceId))) { map.get(clientId).add(InstanceId); } } else { if (!(map.get(clientId).contains(InstanceId))) { map.get(clientId).add(InstanceId); } } } } logger.trace("END HashMap<String,ArrayList<String>> getInstanceIdsPerClientId(TSDBData[] tsdbData)"); return map; } /** * Saves an event POJO to InfluxDB. only for debugging * * @param tsdbData */ //TODO: only for debugging, move to InfluxDBClient private void saveCaughtEvents(TSDBData[] tsdbData) { logger.trace("BEGIN void saveCaughtEvents(TSDBData[] tsdbData)"); for (TSDBData obj : tsdbData) { ArrayList<String> columns = obj.getColumns(); ArrayList<ArrayList<Object>> points = obj.getPoints(); int timeIndex = -1; int statusIndex = -1; int clientidIndex = -1; int instanceidIndex = -1; for (int i = 0; i < columns.size(); i++) { if (columns.get(i).equals("time")) timeIndex = i; else if (columns.get(i).equals("clientid")) clientidIndex = i; else if (columns.get(i).equals("instanceid")) instanceidIndex = i; else if (columns.get(i).equals("status")) statusIndex = i; } for (int i = 0; i < points.size(); i++) { String tablename = "caught_events"; String clientId = points.get(i).get(clientidIndex).toString(); String instanceId = points.get(i).get(instanceidIndex).toString(); dbname = Loader.getSettings().getInfluxDBSettings().getInfluxDBDatabaseName(); String lastevent = points.get(i).get(statusIndex).toString(); if (lastevent.equals(Loader.getSettings().getMcnSettings().getMCNEventStart())) { lastevent = "start"; } else if ((lastevent.equals("stopped")) || (lastevent.equals("STOP"))) { lastevent = "stop"; } try { DateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); Date date = format.parse(points.get(i).get(timeIndex).toString()); long timeMillisec = date.getTime(); System.out.println(timeMillisec); System.out.println(lastevent); Point point = Point.measurement(tablename).field("time", timeMillisec).tag("userid", clientId) .tag("instanceid", instanceId).field("lastevent", lastevent).build(); logger.debug("Attempting to write the Point (" + points.get(i).get(timeIndex) + ") in the db:" + dbname); influxDB.write(Loader.getSettings().getMcnSettings().getMCNDBEventsName(), "default", point); logger.debug("Point successfully written."); } catch (Exception ex) { ex.printStackTrace(); } } } logger.trace("END void saveCaughtEvents(TSDBData[] tsdbData)"); } }