diff --git a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ExampleAlgorithm.java b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ExampleAlgorithm.java index 09bdd637a..f7483d744 100644 --- a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ExampleAlgorithm.java +++ b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ExampleAlgorithm.java @@ -9,10 +9,14 @@ import java.util.Date; import java.util.List; - +/** + * This class provides an Algorithm to calculate the mean ScenarioInstanceRuntime for all terminated ScenarioInstances + * of a Scenario + */ public class ExampleAlgorithm implements AnalyticsService { - static final Logger log = Logger.getLogger(MetaAnalyticsModel.class.getName()); + static final Logger log = Logger.getLogger(ExampleAlgorithm.class.getName()); + @Override /** * This Method calculates the mean runtime for all terminated instances of a scenario * @@ -25,6 +29,11 @@ public JSONObject calculateResult(String[] args) { long avgDuration = 0L; long sumDuration = 0L; int numberOfScenarioInstances = 0; + int millisecondsPerSecond = 1000; + int secondsPerMinute = 60; + int minutesPerHour = 60; + int hoursPerDay = 24; + int daysPerYear = 365; //get instances for scenario List scenarioInstances = MetaAnalyticsModel.getScenarioInstancesForScenario(scenarioId); for (DbScenarioInstanceIDsAndTimestamps scenarioInstance : scenarioInstances) { @@ -44,10 +53,11 @@ public JSONObject calculateResult(String[] args) { return new JSONObject("{\"scenarioId\":" + scenarioId + ",\"meanScenarioInstanceRuntime\":\"No terminated instances.\"}"); } - long second = (avgDuration / 1000) % 60; - long minute = (avgDuration / (1000 * 60)) % 60; - long hour = (avgDuration / (1000 * 60 * 60)) % 24; - long day = (avgDuration / (1000 * 60 * 60 * 24)) % 365; + // converting duration from milliseconds to human readable format days:hours:minutes:seconds + long second = (avgDuration / millisecondsPerSecond) % secondsPerMinute; + long minute = (avgDuration / (millisecondsPerSecond * secondsPerMinute)) % minutesPerHour; + long hour = (avgDuration / (millisecondsPerSecond * secondsPerMinute * minutesPerHour)) % hoursPerDay; + long day = (avgDuration / (millisecondsPerSecond * secondsPerMinute * minutesPerHour * hoursPerDay)) % daysPerYear; String time = String.format("%02d:%02d:%02d:%02d", day, hour, minute, second); String json = "{\"scenarioId\":" + scenarioId + ",\"meanScenarioInstanceRuntime\":\"" + time + "\"}"; diff --git a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ScenarioInstanceRuntime.java b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ScenarioInstanceRuntime.java new file mode 100644 index 000000000..15eac9edf --- /dev/null +++ b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ScenarioInstanceRuntime.java @@ -0,0 +1,84 @@ +package de.uni_potsdam.hpi.bpt.bp2014.janalytics; + +import de.uni_potsdam.hpi.bpt.bp2014.database.Connection; +import org.apache.log4j.Logger; +import org.json.JSONObject; + +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; + +/** + * This class provides an Algorithm to calculate the Runtime for a ScenarioInstance + */ +public class ScenarioInstanceRuntime implements AnalyticsService { + static Logger log = Logger.getLogger(ScenarioInstanceRuntime.class.getName()); + private Date startDate; + + + @Override + /** + * This Method calculates the runtime for a scenarioinstance + * + * @param args used to specify the ScenarioID for which the Instance-Runtime is calculated + * @return a JSONObject containing the scenarioInstanceID and the Instance-Runtime + */ + public JSONObject calculateResult(String[] args) { + int scenarioInstanceId = Integer.parseInt(args[0]); + long duration = 0L; + int millisecondsPerSecond = 1000; + int secondsPerMinute = 60; + int minutesPerHour = 60; + int hoursPerDay = 24; + int daysPerYear = 365; + getStartTimestamp(scenarioInstanceId); + duration = getDuration(); + + // converting duration from milliseconds to human readable format days:hours:minutes:seconds + long second = (duration / millisecondsPerSecond) % secondsPerMinute; + long minute = (duration / (millisecondsPerSecond * secondsPerMinute)) % minutesPerHour; + long hour = (duration / (millisecondsPerSecond * secondsPerMinute * minutesPerHour)) % hoursPerDay; + long day = (duration / (millisecondsPerSecond * secondsPerMinute * minutesPerHour * hoursPerDay)) % daysPerYear; + + String time = String.format("%02d:%02d:%02d:%02d", day, hour, minute, second); + String json = "{\"scenarioId\":" + scenarioInstanceId + ",\"ScenarioInstanceRuntime\":\"" + time + "\"}"; + return new JSONObject(json); + } + + public long getDuration() { + if (startDate == null) { + return (-1); + } + return ((System.currentTimeMillis()) - startDate.getTime()); + } + + public void getStartTimestamp(int scenarioInstanceId) { + + + String sql = "SELECT MIN(timestamp) AS start_timestamp FROM `historydataobjectinstance` as h, scenarioinstance as s WHERE h.scenarioinstance_id = " + scenarioInstanceId + " AND h.scenarioinstance_id = s.id"; + java.sql.Connection conn = Connection.getInstance().connect(); + ResultSet results = null; + try { + results = conn.prepareStatement(sql).executeQuery(); + if (results.next()) { + startDate = results.getTimestamp("start_timestamp"); + + } + + } catch (SQLException e) { + log.error("SQL Error!: ", e); + } finally { + try { + conn.close(); + } catch (SQLException e) { + log.error("SQL Error!: ", e); + } + try { + results.close(); + } catch (SQLException e) { + log.error("SQL Error!: ", e); + } + } + + } +} diff --git a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ServiceManager.java b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ServiceManager.java index 57690ce78..51299e15b 100644 --- a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ServiceManager.java +++ b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/ServiceManager.java @@ -34,10 +34,17 @@ public Set getServices() { * * @param service the service. * @param args arguments for the service. + * @return resultId representing the calculated result of the service in the database */ - public void calculateResultForService(String service, String[] args) { + public int calculateResultForService(String service, String[] args) { + int resultId = -1; JSONObject jsonObject = services.get(service).calculateResult(args); - dbObject.executeUpdateStatement("UPDATE janalyticsresults SET json = '" + jsonObject.toString() + "' WHERE service = '" + services.get(service).getClass().getName() + "'"); + //dbObject.executeUpdateStatement("UPDATE janalyticsresults SET json = '" + jsonObject.toString() + "' WHERE service = '" + services.get(service).getClass().getName() + "'"); + resultId = dbObject.executeInsertStatement("INSERT INTO janalyticsresults (service, json) VALUES ('" + services.get(service).getClass().getName() + "', '" + jsonObject.toString() + "')"); + /*if (!dbObject.executeExistStatement("SELECT * FROM janalyticsresults WHERE service = '" + services.get(service).getClass().getName() + "'")) { + * dbObject.executeInsertStatement("INSERT INTO janalyticsresults (service, json) VALUES ('" + services.get(service).getClass().getName() + "', '{}')"); + }*/ + return resultId; } /** @@ -50,14 +57,16 @@ public boolean existService(String service) { return services.containsKey(service); } + /** - * Gives the Result for a service. Returns it as json. The json could be empty if the service never calculated a result. + * Gives the Result for a service and ID. Returns it as json. The json could be empty if the service never calculated a result. * * @param service the service. + * @param resultId the id to identify the calculated result * @return a json with the result of the service. */ - public JSONObject getResultForService(String service) { - String json = dbObject.executeStatementReturnsString("SELECT json FROM janalyticsresults WHERE service = '" + services.get(service).getClass().getName() + "'", "json"); + public JSONObject getResultForServiceViaId(String service, int resultId) { + String json = dbObject.executeStatementReturnsString("SELECT json FROM janalyticsresults WHERE id = '" + resultId + "' AND service = '" + services.get(service).getClass().getName() + "'", "json"); return new JSONObject(json); } @@ -69,9 +78,7 @@ public JSONObject getResultForService(String service) { private void addService(AnalyticsService service) { String serviceName = service.getClass().getName(); services.put(serviceName, service); - if (!dbObject.executeExistStatement("SELECT * FROM janalyticsresults WHERE service = '" + serviceName + "'")) { - dbObject.executeInsertStatement("INSERT INTO janalyticsresults (service, json) VALUES ('" + serviceName + "', '{}')"); - } + } /** @@ -79,6 +86,7 @@ private void addService(AnalyticsService service) { */ private void registerServices() { addService(new ExampleAlgorithm()); + addService(new ScenarioInstanceRuntime()); // add further Algorithms here } } diff --git a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/rest/RestInterface.java b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/rest/RestInterface.java index 09f63fa56..1ffec30d8 100644 --- a/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/rest/RestInterface.java +++ b/src/main/java/de/uni_potsdam/hpi/bpt/bp2014/janalytics/rest/RestInterface.java @@ -6,8 +6,12 @@ import org.json.JSONObject; import javax.ws.rs.*; +import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import javax.ws.rs.core.UriInfo; +import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; @@ -34,21 +38,21 @@ public Response getServices() { /** * Returns the result of an service. - * + * @param resultId represents the calculated result for a service in the database * @param service the specific service. * @return JSON with the result. */ @GET - @Path("services/{service}") + @Path("services/{service}/result/{resultID}") @Produces(MediaType.APPLICATION_JSON) - public Response getServiceResults(@PathParam("service") String service) { + public Response getServiceResults(@PathParam("service") String service, @PathParam("resultID") int resultId) { if (!serviceManager.existService(service)) { return Response.status(Response.Status.NOT_FOUND) .type(MediaType.APPLICATION_JSON) .entity("{\"error\":\"There is no service " + service + "\"}") .build(); } - JSONObject jsonObject = serviceManager.getResultForService(service); + JSONObject jsonObject = serviceManager.getResultForServiceViaId(service, resultId); return Response.ok(jsonObject.toString(), MediaType.APPLICATION_JSON).build(); } @@ -62,7 +66,9 @@ public Response getServiceResults(@PathParam("service") String service) { @POST @Path("services/{service}") @Produces(MediaType.APPLICATION_JSON) - public Response calculateServiceResults(@PathParam("service") String service, String json) { + public Response calculateServiceResults( + @Context UriInfo uriInfo, @PathParam("service") String service, String json) { + int resultId; if (!serviceManager.existService(service)) { return Response.status(Response.Status.NOT_FOUND) .type(MediaType.APPLICATION_JSON) @@ -70,7 +76,7 @@ public Response calculateServiceResults(@PathParam("service") String service, St .build(); } if (json.equals("")) { - serviceManager.calculateResultForService(service, new String[0]); + resultId = serviceManager.calculateResultForService(service, new String[0]); } else { ArrayList list = new ArrayList<>(); JSONArray jsonArray; @@ -89,7 +95,13 @@ public Response calculateServiceResults(@PathParam("service") String service, St list.add(jsonArray.get(i).toString()); } } - serviceManager.calculateResultForService(service, list.toArray(new String[list.size()])); + resultId = serviceManager.calculateResultForService(service, list.toArray(new String[list.size()])); + } + //return Response.ok("{}", MediaType.APPLICATION_JSON).build(); + try { + return Response.seeOther(new URI(uriInfo.getAbsolutePath() + "/result/"+ resultId)).build(); + } catch (URISyntaxException e) { + e.printStackTrace(); } return Response.ok("{}", MediaType.APPLICATION_JSON).build(); } diff --git a/src/main/resources/JEngineV2_schema.sql b/src/main/resources/JEngineV2_schema.sql index 104a1220b..58e492744 100644 --- a/src/main/resources/JEngineV2_schema.sql +++ b/src/main/resources/JEngineV2_schema.sql @@ -392,10 +392,12 @@ CREATE TABLE IF NOT EXISTS `historydataobjectinstance` ( -- CREATE TABLE IF NOT EXISTS `janalyticsresults` ( + `id` int(11) NOT NULL AUTO_INCREMENT, `service` varchar(256) NOT NULL, `json` text, - PRIMARY KEY (`service`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1; + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; + -- -------------------------------------------------------- diff --git a/src/main/webapp/asset/js/modules/userInteraction.js b/src/main/webapp/asset/js/modules/userInteraction.js index 0de802187..a53a0543a 100644 --- a/src/main/webapp/asset/js/modules/userInteraction.js +++ b/src/main/webapp/asset/js/modules/userInteraction.js @@ -39,10 +39,11 @@ $http.post(JEngine_Server_URL + "/" + JAnalytics_REST_Interface + "/services/" + algorithm, {"args": [id]}) .success(function (data) { // retrieving results of algorithm as soon as POST is done successfully - $http.get(JEngine_Server_URL + JAnalytics_REST_Interface + "/services/" + algorithm) + controller.currentScenario['duration'] = data['meanScenarioInstanceRuntime']; + /*$http.get(JEngine_Server_URL + JAnalytics_REST_Interface + "/services/" + algorithm) .success(function (data) { controller.currentScenario['duration'] = data['meanScenarioInstanceRuntime']; - }) + })*/ }) }). error(function () { @@ -272,6 +273,17 @@ success(function (data) { instanceCtrl.scenario['instances'] = data; instanceCtrl.scenario['id'] = $routeParams.id; + angular.forEach(instanceCtrl.scenario['instances']['ids'], function(scenarioInstance, key) { + $http.post(JEngine_Server_URL + "/" + JAnalytics_REST_Interface + + "/services/de.uni_potsdam.hpi.bpt.bp2014.janalytics.ScenarioInstanceRuntime", + {"args":[scenarioInstance]}).success(function(data) { + if (!instanceCtrl.scenario['instances']['durations']) { + instanceCtrl.scenario['instances']['durations'] = {}; + } + instanceCtrl.scenario['instances']['durations'][data['scenarioId']] = data['ScenarioInstanceRuntime']; + console.log(data); + }) + }) }).error(function () { console.log('request failed'); });