Repository: incubator-cmda Updated Branches: refs/heads/master ca952ad97 -> d6e12b893
update backend: Add Relational Knowledge Graph APIs and modified data models Project: http://git-wip-us.apache.org/repos/asf/incubator-cmda/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-cmda/commit/d6e12b89 Tree: http://git-wip-us.apache.org/repos/asf/incubator-cmda/tree/d6e12b89 Diff: http://git-wip-us.apache.org/repos/asf/incubator-cmda/diff/d6e12b89 Branch: refs/heads/master Commit: d6e12b8933f710469dce527cb58c217322a5d562 Parents: ca952ad Author: mingqi830 <m...@andrew.cmu.edu> Authored: Tue Nov 10 16:45:49 2015 -0800 Committer: mingqi830 <m...@andrew.cmu.edu> Committed: Tue Nov 10 16:45:49 2015 -0800 ---------------------------------------------------------------------- ApacheCMDA_Backend_1.0/.DS_Store | Bin 12292 -> 12292 bytes .../app/controllers/AnalyticsController.java | 629 ++++++++++++++++++- .../controllers/ClimateServiceController.java | 57 ++ .../ServiceExecutionLogController.java | 19 +- .../app/controllers/WorkflowController.java | 8 +- .../app/models/ClimateServiceRepository.java | 4 + .../app/models/DatasetAndUserRepository.java | 7 +- .../app/models/ServiceAndDataset.java | 68 ++ .../app/models/ServiceAndDatasetRepository.java | 18 + .../app/models/ServiceAndUser.java | 69 ++ .../app/models/ServiceAndUserRepository.java | 18 + ApacheCMDA_Backend_1.0/app/util/Matrix.java | 234 +++++++ ApacheCMDA_Backend_1.0/conf/.DS_Store | Bin 0 -> 6148 bytes ApacheCMDA_Backend_1.0/conf/routes | 12 +- 14 files changed, 1117 insertions(+), 26 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/.DS_Store ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/.DS_Store b/ApacheCMDA_Backend_1.0/.DS_Store index 5495852..d540f2b 100644 Binary files a/ApacheCMDA_Backend_1.0/.DS_Store and b/ApacheCMDA_Backend_1.0/.DS_Store differ http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/controllers/AnalyticsController.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/controllers/AnalyticsController.java b/ApacheCMDA_Backend_1.0/app/controllers/AnalyticsController.java index feed694..f5f44d4 100644 --- a/ApacheCMDA_Backend_1.0/app/controllers/AnalyticsController.java +++ b/ApacheCMDA_Backend_1.0/app/controllers/AnalyticsController.java @@ -9,33 +9,409 @@ import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; +import models.ClimateService; +import models.ClimateServiceRepository; +import models.Dataset; import models.DatasetAndUser; import models.DatasetAndUserRepository; +import models.DatasetRepository; +import models.ServiceAndDataset; +import models.ServiceAndDatasetRepository; +import models.ServiceAndUser; +import models.ServiceAndUserRepository; +import models.User; +import models.UserRepository; import play.mvc.Controller; import play.mvc.Result; +import util.Matrix; +import com.fasterxml.jackson.databind.JsonNode; import com.google.gson.Gson; @Named @Singleton -public class AnalyticsController extends Controller{ +public class AnalyticsController extends Controller { + private final DatasetAndUserRepository datasetAndUserRepository; + private final ServiceAndUserRepository serviceAndUserRepository; + private final ServiceAndDatasetRepository serviceAndDatasetRepository; + private final UserRepository userRepository; + private final DatasetRepository datasetRepository; + private final ClimateServiceRepository serviceRepository; + @Inject - public AnalyticsController(DatasetAndUserRepository datasetAndUserRepository) { + public AnalyticsController( + DatasetAndUserRepository datasetAndUserRepository, + ServiceAndUserRepository serviceAndUserRepository, + ServiceAndDatasetRepository serviceAndDatasetRepository, + UserRepository userRepository, DatasetRepository datasetRepository, + ClimateServiceRepository serviceRepository) { this.datasetAndUserRepository = datasetAndUserRepository; + this.serviceAndUserRepository = serviceAndUserRepository; + this.serviceAndDatasetRepository = serviceAndDatasetRepository; + this.userRepository = userRepository; + this.datasetRepository = datasetRepository; + this.serviceRepository = serviceRepository; + } + + public long getResultCount(String param) { + long count = 0; + switch (param) { + case "User": + count = userRepository.count(); + break; + case "Dataset": + count = datasetRepository.count(); + break; + case "Service": + count = serviceRepository.count(); + break; + default: + break; + } + return count; } - public Result getAllDatasetAndUserWithCount(String format) { + public Map<String, Object> generateRelationalMap(String param1, String param2, String param3) { + String option = param1 + param2 + param3; + Map<String, Object> map = new HashMap<>(); + int[][] relations = null; + int count1 = (int) getResultCount(param1), count3 = (int) getResultCount(param3); + + switch (option) { + case "UserUserDataset": { + relations = new int[count1][count3]; + Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository + .findAll(); + + if (datasetAndUsers == null) { + System.out.println("User and Dataset: cannot be found!"); + } + + for (DatasetAndUser one : datasetAndUsers) { + int i = (int) one.getUser().getId() - 1; + int j = (int) one.getDataset().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "user"); + break; + } + case "UserUserService": { + relations = new int[count1][count3]; + Iterable<ServiceAndUser> serviceAndUsers = serviceAndUserRepository + .findAll(); + + if (serviceAndUsers == null) { + System.out.println("User and Service: cannot be found!"); + } + + for (ServiceAndUser one : serviceAndUsers) { + int i = (int) one.getUser().getId() - 1; + int j = (int) one.getClimateService().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "user"); + break; + } + case "DatasetDatasetUser": { + relations = new int[count1][count3]; + Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository + .findAll(); + + if (datasetAndUsers == null) { + System.out.println("User and Dataset: cannot be found!"); + } + + for (DatasetAndUser one : datasetAndUsers) { + int i = (int) one.getDataset().getId() - 1; + int j = (int) one.getUser().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "dataset"); + break; + } + case "DatasetDatasetService": { + relations = new int[count1][count3]; + Iterable<ServiceAndDataset> datasetAndServices = serviceAndDatasetRepository + .findAll(); + + if (datasetAndServices == null) { + System.out.println("Dataset and Service: cannot be found!"); + } + + for (ServiceAndDataset one : datasetAndServices) { + int i = (int) one.getDataset().getId() - 1; + int j = (int) one.getClimateService().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "dataset"); + break; + } + case "ServiceServiceUser": { + relations = new int[count1][count3]; + Iterable<ServiceAndUser> serviceAndUsers = serviceAndUserRepository + .findAll(); + + if (serviceAndUsers == null) { + System.out.println("User and Service: cannot be found!"); + } + + for (ServiceAndUser one : serviceAndUsers) { + int i = (int) one.getClimateService().getId() - 1; + int j = (int) one.getUser().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "service"); + break; + } + case "ServiceServiceDataset": { + relations = new int[count1][count3]; + Iterable<ServiceAndDataset> datasetAndServices = serviceAndDatasetRepository + .findAll(); + + if (datasetAndServices == null) { + System.out.println("Dataset and Service: cannot be found!"); + } + + for (ServiceAndDataset one : datasetAndServices) { + int i = (int) one.getClimateService().getId() - 1; + int j = (int) one.getDataset().getId() - 1; + relations[i][j] = (int) one.getCount(); + } + + Matrix m1 = new Matrix(relations); + Matrix m2 = m1.transpose(); + Matrix m3 = m1.times(m2); + int[][] res = m3.getArray(); + + map = jsonFormatForMatrix(res, "service"); + break; + } + case "UserDatasetService": + map = getAllDatasetAndUserWithCount(); + break; + case "UserServiceDataset": + map = getAllServiceAndUserWithCount(); + break; + case "DatasetServiceUser": + map = getAllServiceAndDatasetWithCount(); + break; + default: + break; + } + return map; + } + + public Result getRelationalKnowledgeGraph(String format) { + JsonNode json = request().body().asJson(); + + if (json == null) { + System.out.println("Cannot find relational knowledge graph, expecting Json data"); + return badRequest("Cannot find relational knowledge graph, expecting Json data"); + } + String param1 = json.findPath("param1").asText(); + String param2 = json.findPath("param2").asText(); + String param3 = json.findPath("param3").asText(); + + try { + Map<String, Object> map = generateRelationalMap(param1, param2, param3); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + return ok(result); + } catch (Exception e) { + return badRequest("Relationship not found"); + } + + } + + public Map<String, Object> getAllServiceAndDatasetWithCount() { + + Iterable<ServiceAndDataset> datasetAndServices = serviceAndDatasetRepository + .findAll(); + + if (datasetAndServices == null) { + System.out.println("Dataset and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndDataset(datasetAndServices); + return map; + + } + + public Map<String, Object> getAllDatasetAndUserWithCount() { + + Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository + .findAll(); + + if (datasetAndUsers == null) { + System.out.println("User and Dataset: cannot be found!"); + } + + Map<String, Object> map = jsonFormatUserAndDataset(datasetAndUsers); + return map; + } + + public Map<String, Object> getAllServiceAndUserWithCount() { + + Iterable<ServiceAndUser> serviceAndUsers = serviceAndUserRepository + .findAll(); + + if (serviceAndUsers == null) { + System.out.println("User and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndUser(serviceAndUsers); + return map; + } + + public Result getOneUserWithAllDatasetAndCount(long userId, String format) { try { - Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository.findAll(); + User user = userRepository.findOne(userId); + Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository + .findByUser(user); if (datasetAndUsers == null) { System.out.println("User and Dataset: cannot be found!"); return notFound("User and Dataset: cannot be found!"); - } + } + + Map<String, Object> map = jsonFormatUserAndDataset(datasetAndUsers); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + + return ok(result); + } catch (Exception e) { + return badRequest("User and Dataset not found"); + } + } + + public Result getOneDatasetWithAllDatasetAndCount(long datasetId, + String format) { + + try { + Dataset dataset = datasetRepository.findOne(datasetId); + Iterable<DatasetAndUser> datasetAndUsers = datasetAndUserRepository + .findByDataset(dataset); + + if (datasetAndUsers == null) { + System.out.println("User and Dataset: cannot be found!"); + return notFound("User and Dataset: cannot be found!"); + } + + Map<String, Object> map = jsonFormatUserAndDataset(datasetAndUsers); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + + return ok(result); + } catch (Exception e) { + return badRequest("User and Dataset not found"); + } + } + + public Result getOneUserWithAllServiceAndCount(long userId, String format) { + + try { + User user = userRepository.findOne(userId); + Iterable<ServiceAndUser> serviceAndUsers = serviceAndUserRepository + .findByUser(user); + + if (serviceAndUsers == null) { + System.out.println("User and Service: cannot be found!"); + return notFound("User and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndUser(serviceAndUsers); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + + return ok(result); + } catch (Exception e) { + return badRequest("User and Service not found"); + } + } + + public Result getOneServiceWithAllUserAndCount(long serviceId, String format) { + + try { + ClimateService service = serviceRepository.findOne(serviceId); + Iterable<ServiceAndUser> serviceAndUsers = serviceAndUserRepository + .findByClimateService(service); + + if (serviceAndUsers == null) { + System.out.println("User and Service: cannot be found!"); + return notFound("User and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndUser(serviceAndUsers); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + + return ok(result); + } catch (Exception e) { + return badRequest("User and Service not found"); + } + } + + public Result getOneServiceWithAllDatasetAndCount(long serviceId, + String format) { - Map<String, Object> map = jsonFormat(datasetAndUsers); + try { + ClimateService service = serviceRepository.findOne(serviceId); + Iterable<ServiceAndDataset> datasetAndServices = serviceAndDatasetRepository + .findByClimateService(service); + + if (datasetAndServices == null) { + System.out.println("Dataset and Service: cannot be found!"); + return notFound("Dataset and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndDataset(datasetAndServices); String result = new String(); if (format.equals("json")) { @@ -44,11 +420,38 @@ public class AnalyticsController extends Controller{ return ok(result); } catch (Exception e) { - return badRequest("DatasetLog not found"); + return badRequest("Dataset and Service not found"); } } - private Map<String, Object> jsonFormat(Iterable<DatasetAndUser> userDatasets) { + public Result getOneDatasetWithAllServiceAndCount(long datasetId, + String format) { + + try { + Dataset dataset = datasetRepository.findOne(datasetId); + Iterable<ServiceAndDataset> datasetAndServices = serviceAndDatasetRepository + .findByDataset(dataset); + + if (datasetAndServices == null) { + System.out.println("Dataset and Service: cannot be found!"); + return notFound("Dataset and Service: cannot be found!"); + } + + Map<String, Object> map = jsonFormatServiceAndDataset(datasetAndServices); + + String result = new String(); + if (format.equals("json")) { + result = new Gson().toJson(map); + } + + return ok(result); + } catch (Exception e) { + return badRequest("Dataset and Service not found"); + } + } + + private Map<String, Object> jsonFormatUserAndDataset( + Iterable<DatasetAndUser> userDatasets) { List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>(); List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>(); @@ -59,31 +462,148 @@ public class AnalyticsController extends Controller{ int target = 0; // Check whether the current user has already existed for (int j = 0; j < nodes.size(); j++) { - if (nodes.get(j).get("title") - .equals(userDataset.getUser().getUserName())) { + if (nodes.get(j).get("group").equals("user") + && (long) nodes.get(j).get("userId") == userDataset + .getUser().getId()) { + source = (int) nodes.get(j).get("id"); + break; + } + } + if (source == 0) { + String realName = userDataset.getUser().getFirstName() + " " + + userDataset.getUser().getLastName(); + nodes.add(map7("id", i, "title", realName, "label", userDataset + .getUser().getUserName(), "cluster", "1", "value", 1, + "group", "user", "userId", userDataset.getUser() + .getId())); + + source = i; + i++; + } + // Check whether the current dataset has already existed + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals("dataset") + && (long) nodes.get(j).get("datasetId") == userDataset + .getDataset().getId()) { + target = (int) nodes.get(j).get("id"); + break; + } + } + if (target == 0) { + nodes.add(map7("id", i, "title", userDataset.getDataset() + .getName(), "label", + userDataset.getDataset().getName(), "cluster", "2", + "value", 2, "group", "dataset", "datasetId", + userDataset.getDataset().getId())); + target = i; + i++; + } + rels.add(map3("from", source, "to", target, "title", "USE")); + + } + + return map("nodes", nodes, "edges", rels); + } + + private Map<String, Object> jsonFormatServiceAndDataset( + Iterable<ServiceAndDataset> serviceDatasets) { + + List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>(); + List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>(); + + int i = 1; + for (ServiceAndDataset serviceDataset : serviceDatasets) { + int source = 0; + int target = 0; + // Check whether the current service has already existed + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals("service") + && (long) nodes.get(j).get("serviceId") == serviceDataset + .getClimateService().getId()) { source = (int) nodes.get(j).get("id"); break; } } if (source == 0) { - nodes.add(map6("id", i, "title", userDataset.getUser() - .getUserName(), "label", "user", "cluster", "1", - "value", 1, "group", "user")); + nodes.add(map7("id", i, "title", serviceDataset + .getClimateService().getName(), "label", serviceDataset + .getClimateService().getName(), "cluster", "3", + "value", 1, "group", "service", "serviceId", + serviceDataset.getClimateService().getId())); source = i; i++; } // Check whether the current dataset has already existed for (int j = 0; j < nodes.size(); j++) { - if (nodes.get(j).get("title") - .equals(userDataset.getDataset().getName())) { + if (nodes.get(j).get("group").equals("dataset") + && (long) nodes.get(j).get("datasetId") == serviceDataset + .getDataset().getId()) { target = (int) nodes.get(j).get("id"); break; } } if (target == 0) { - nodes.add(map6("id", i, "title", userDataset.getDataset() - .getName(), "label", "dataset", "cluster", "2", - "value", 2, "group", "dataset")); + nodes.add(map7("id", i, "title", serviceDataset.getDataset() + .getName(), "label", serviceDataset.getDataset() + .getName(), "cluster", "2", "value", 2, "group", + "dataset", "datasetId", serviceDataset.getDataset() + .getId())); + target = i; + i++; + } + + rels.add(map3("from", source, "to", target, "title", "Utilize")); + + } + + return map("nodes", nodes, "edges", rels); + } + + private Map<String, Object> jsonFormatServiceAndUser( + Iterable<ServiceAndUser> userServices) { + + List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>(); + List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>(); + + int i = 1; + for (ServiceAndUser userService : userServices) { + int source = 0; + int target = 0; + // Check whether the current user has already existed + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals("user") + && (long) nodes.get(j).get("userId") == userService + .getUser().getId()) { + source = (int) nodes.get(j).get("id"); + break; + } + } + if (source == 0) { + String realName = userService.getUser().getFirstName() + " " + + userService.getUser().getMiddleInitial() + " " + + userService.getUser().getLastName(); + nodes.add(map7("id", i, "title", realName, "label", userService + .getUser().getUserName(), "cluster", "1", "value", 1, + "group", "user", "userId", userService.getUser() + .getId())); + source = i; + i++; + } + // Check whether the current service has already existed + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals("service") + && (long) nodes.get(j).get("serviceId") == userService + .getClimateService().getId()) { + target = (int) nodes.get(j).get("id"); + break; + } + } + if (target == 0) { + nodes.add(map7("id", i, "title", userService + .getClimateService().getName(), "label", userService + .getClimateService().getName(), "cluster", "3", + "value", 2, "group", "service", "serviceId", + userService.getClimateService().getId())); target = i; i++; } @@ -94,6 +614,74 @@ public class AnalyticsController extends Controller{ return map("nodes", nodes, "edges", rels); } + + public String findTitleName(String param, long id) { + String title = ""; + switch (param) { + case "user": + title = userRepository.findOne(id).getUserName(); + break; + case "dataset": + title = datasetRepository.findOne(id).getName(); + break; + case "service": + title = serviceRepository.findOne(id).getName(); + break; + default: + break; + } + return title; + } + + private Map<String, Object> jsonFormatForMatrix(int[][] matrix, String param) { + + List<Map<String, Object>> nodes = new ArrayList<Map<String, Object>>(); + List<Map<String, Object>> rels = new ArrayList<Map<String, Object>>(); + + int i = 1; + for (int m = 0; m < matrix.length; m++) { + for (int n = m + 1; n < matrix[0].length; n++) { + if (matrix[m][n] > 0) { + int source = 0; + int target = 0; + // Check whether the current user has already existed + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals(param) + && (long) nodes.get(j).get(param + "Id") == (long)m + 1) { + source = (int) nodes.get(j).get("id"); + break; + } + } + if (source == 0) { + String name = findTitleName(param, (long)m+1); + nodes.add(map7("id", i, "title", name, "label", + name, "cluster", "1", "value", 1, "group", + param, param + "Id", (long)m + 1)); + source = i; + i++; + } + for (int j = 0; j < nodes.size(); j++) { + if (nodes.get(j).get("group").equals(param) + && (long) nodes.get(j).get(param + "Id") == (long)n + 1) { + target = (int) nodes.get(j).get("id"); + break; + } + } + if (target == 0) { + String name = findTitleName(param, (long)n+1); + nodes.add(map7("id", i, "title", name, "label", + name, "cluster", "1", "value", 1, "group", + param, param + "Id", (long)n + 1)); + target = i; + i++; + } + rels.add(map3("from", source, "to", target, "title", "RELATE")); + } + } + } + + return map("nodes", nodes, "edges", rels); + } private Map<String, Object> map(String key1, Object value1, String key2, Object value2) { @@ -112,10 +700,10 @@ public class AnalyticsController extends Controller{ return result; } - private Map<String, Object> map6(String key1, Object value1, String key2, + private Map<String, Object> map7(String key1, Object value1, String key2, Object value2, String key3, Object value3, String key4, Object value4, String key5, Object value5, String key6, - Object value6) { + Object value6, String key7, Object value7) { Map<String, Object> result = new HashMap<String, Object>(6); result.put(key1, value1); result.put(key2, value2); @@ -123,6 +711,7 @@ public class AnalyticsController extends Controller{ result.put(key4, value4); result.put(key5, value5); result.put(key6, value6); + result.put(key7, value7); return result; } } http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/controllers/ClimateServiceController.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/controllers/ClimateServiceController.java b/ApacheCMDA_Backend_1.0/app/controllers/ClimateServiceController.java index 700ad68..e42f8b6 100644 --- a/ApacheCMDA_Backend_1.0/app/controllers/ClimateServiceController.java +++ b/ApacheCMDA_Backend_1.0/app/controllers/ClimateServiceController.java @@ -32,6 +32,7 @@ import com.google.gson.Gson; @Named @Singleton public class ClimateServiceController extends Controller { + public static final String WILDCARD = "%"; private final int initialcount = 0; // static final String DATE_PATTERN = "yyyy-MM-dd'T'HH:mm:ssz"; @@ -490,4 +491,60 @@ public class ClimateServiceController extends Controller { } return ok(result); } + + public Result queryClimateServices() { + JsonNode json = request().body().asJson(); + if (json == null) { + System.out.println("ClimateService cannot be queried, expecting Json data"); + return badRequest("ClimateService cannot be queried, expecting Json data"); + } + String result = new String(); + try { + //Parse JSON file + String name = json.path("name").asText(); + if (name.isEmpty()) { + name = WILDCARD; + } + else { + name = WILDCARD+name+WILDCARD; + } + String purpose = json.path("purpose").asText(); + if (purpose.isEmpty()) { + purpose = WILDCARD; + } + else { + purpose = WILDCARD+purpose+WILDCARD; + } + String url = json.path("url").asText(); + if (url.isEmpty()) { + url = WILDCARD; + } + else { + url = WILDCARD+url+WILDCARD; + } + String scenario = json.path("scenario").asText(); + if (scenario.isEmpty()) { + scenario = WILDCARD; + } + else { + scenario = WILDCARD+scenario+WILDCARD; + } + String versionNo = json.path("versionNo").asText(); + if (versionNo.isEmpty()) { + versionNo = WILDCARD; + } + else { + versionNo = WILDCARD+versionNo+WILDCARD; + } + + List<ClimateService> climateServices = climateServiceRepository.findClimateService(name, purpose, url, scenario, versionNo); + result = new Gson().toJson(climateServices); + } catch (Exception e) { + System.out.println("ServiceExecutionLog cannot be queried, query is corrupt"); + return badRequest("ServiceExecutionLog cannot be queried, query is corrupt"); + } + + System.out.println("*******************************\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&\n" + result); + return ok(result); + } } http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/controllers/ServiceExecutionLogController.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/controllers/ServiceExecutionLogController.java b/ApacheCMDA_Backend_1.0/app/controllers/ServiceExecutionLogController.java index e4594a8..9d5dad2 100644 --- a/ApacheCMDA_Backend_1.0/app/controllers/ServiceExecutionLogController.java +++ b/ApacheCMDA_Backend_1.0/app/controllers/ServiceExecutionLogController.java @@ -12,6 +12,8 @@ import javax.persistence.PersistenceException; import models.ClimateService; import models.ClimateServiceRepository; import models.Dataset; +import models.DatasetAndUser; +import models.DatasetAndUserRepository; import models.DatasetEntry; import models.DatasetEntryRepository; import models.DatasetLog; @@ -54,6 +56,7 @@ public class ServiceExecutionLogController extends Controller { private final ServiceConfigurationItemRepository serviceConfigurationItemRepository; private final DatasetLogRepository datasetLogRepository; private final ServiceConfigurationRepository serviceConfigurationRepository; + private final DatasetAndUserRepository datasetAndUserRepository; // We are using constructor injection to receive a repository to support our // desire for immutability. @@ -68,7 +71,8 @@ public class ServiceExecutionLogController extends Controller { ServiceConfigurationRepository serviceConfigurationRepository, ServiceEntryRepository serviceEntryRepository, DatasetEntryRepository datasetEntryRepository, - DatasetRepository datasetRepository) { + DatasetRepository datasetRepository, + DatasetAndUserRepository datasetAndUserRepository) { this.parameterRepository = parameterRepository; this.serviceExecutionLogRepository = serviceExecutionLogRepository; this.userRepository = userRepository; @@ -79,6 +83,7 @@ public class ServiceExecutionLogController extends Controller { this.serviceEntryRepository = serviceEntryRepository; this.datasetEntryRepository = datasetEntryRepository; this.datasetRepository = datasetRepository; + this.datasetAndUserRepository = datasetAndUserRepository; } public Result queryServiceExecutionLogs() { @@ -477,8 +482,18 @@ public class ServiceExecutionLogController extends Controller { dataset, user, plotUrl, dataUrl, dataset, dataset, datasetStudyStartTime, datasetStudyEndTime); DatasetLog savedDatasetLog = datasetLogRepository.save(datasetLog); - System.out.println(dataset.toString()); System.out.print("DatasetLog saved:" + savedDatasetLog.getId()); + + List<DatasetAndUser> datasetAndUsers = datasetAndUserRepository.findByUserAndDataset(user, dataset); + if(datasetAndUsers.size() == 0) { + DatasetAndUser datasetAndUser = new DatasetAndUser(user, dataset, 0); + datasetAndUserRepository.save(datasetAndUser); + } + else { + DatasetAndUser datasetAndUser = datasetAndUsers.get(0); + datasetAndUser.setCount(datasetAndUser.getCount() + 1); + datasetAndUserRepository.save(datasetAndUser); + } } } http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/controllers/WorkflowController.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/controllers/WorkflowController.java b/ApacheCMDA_Backend_1.0/app/controllers/WorkflowController.java index e01909a..41c9e99 100644 --- a/ApacheCMDA_Backend_1.0/app/controllers/WorkflowController.java +++ b/ApacheCMDA_Backend_1.0/app/controllers/WorkflowController.java @@ -24,6 +24,7 @@ import com.google.gson.Gson; import models.ClimateService; import models.ClimateServiceRepository; +import models.DatasetAndUserRepository; import models.DatasetEntryRepository; import models.DatasetLogRepository; import models.DatasetRepository; @@ -59,6 +60,7 @@ public class WorkflowController extends Controller { private final ServiceEntryRepository serviceEntryRepository; private final DatasetEntryRepository datasetEntryRepository; private final DatasetRepository datasetRepository; + private final DatasetAndUserRepository datasetAndUserRepository; @Inject public WorkflowController( @@ -72,7 +74,8 @@ public class WorkflowController extends Controller { ServiceConfigurationRepository serviceConfigurationRepository, ServiceEntryRepository serviceEntryRepository, DatasetEntryRepository datasetEntryRepository, - DatasetRepository datasetRepository) { + DatasetRepository datasetRepository, + DatasetAndUserRepository datasetAndUserRepository) { this.climateServiceRepository = climateServiceRepository; this.userRepository = userRepository; this.workflowRepository = workflowRepository; @@ -84,6 +87,7 @@ public class WorkflowController extends Controller { this.serviceEntryRepository = serviceEntryRepository; this.datasetEntryRepository = datasetEntryRepository; this.datasetRepository = datasetRepository; + this.datasetAndUserRepository = datasetAndUserRepository; } public Result addWorkflow() { @@ -227,7 +231,7 @@ public class WorkflowController extends Controller { serviceConfigurationItemRepository, userRepository, climateServiceRepository, datasetLogRepository, serviceConfigurationRepository, serviceEntryRepository, - datasetEntryRepository, datasetRepository); + datasetEntryRepository, datasetRepository, datasetAndUserRepository); List<ServiceExecutionLog> list = serviceExecutionLogController .queryServiceExecutionLogsAsList(); String result = VisTrailJson.getVisTrailJson(list); http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/ClimateServiceRepository.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/ClimateServiceRepository.java b/ApacheCMDA_Backend_1.0/app/models/ClimateServiceRepository.java index 2f70c53..5a8090b 100644 --- a/ApacheCMDA_Backend_1.0/app/models/ClimateServiceRepository.java +++ b/ApacheCMDA_Backend_1.0/app/models/ClimateServiceRepository.java @@ -24,4 +24,8 @@ public interface ClimateServiceRepository extends CrudRepository<ClimateService, @Query(value = "select * from ClimateService where id in (select serviceId from ServiceEntry s where serviceId in (select climateServiceId from DatasetAndService where datasetId=?2) group by s.serviceId order by s.latestAccessTimeStamp desc) limit ?1", nativeQuery = true) List<ClimateService> getClimateServiceByDatasetId(int k, long id); + + @Query(value = "select * from ClimateService where ((name like ?1) and (purpose like ?2) and (url like ?3) and (scenario like ?4) and (versionNo like ?5))", nativeQuery = true) + List<ClimateService> findClimateService(String name, String purpose, String url, String scenario, String versionNo); + } http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/DatasetAndUserRepository.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/DatasetAndUserRepository.java b/ApacheCMDA_Backend_1.0/app/models/DatasetAndUserRepository.java index ce6b046..f6d8e27 100644 --- a/ApacheCMDA_Backend_1.0/app/models/DatasetAndUserRepository.java +++ b/ApacheCMDA_Backend_1.0/app/models/DatasetAndUserRepository.java @@ -1,5 +1,7 @@ package models; +import java.util.List; + import org.springframework.data.repository.CrudRepository; import javax.inject.Named; @@ -8,5 +10,8 @@ import javax.inject.Singleton; @Named @Singleton public interface DatasetAndUserRepository extends CrudRepository<DatasetAndUser, Long> { - + + List<DatasetAndUser> findByUserAndDataset(User user, Dataset dataset); + List<DatasetAndUser> findByUser(User user); + List<DatasetAndUser> findByDataset(Dataset dataset); } http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/ServiceAndDataset.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/ServiceAndDataset.java b/ApacheCMDA_Backend_1.0/app/models/ServiceAndDataset.java new file mode 100644 index 0000000..8ae0392 --- /dev/null +++ b/ApacheCMDA_Backend_1.0/app/models/ServiceAndDataset.java @@ -0,0 +1,68 @@ +package models; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +@Entity +public class ServiceAndDataset { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @ManyToOne(optional = false) + @JoinColumn(name = "serviceId", referencedColumnName = "id") + private ClimateService climateService; + @ManyToOne(optional = false) + @JoinColumn(name = "datasetId", referencedColumnName = "id") + private Dataset dataset; + private long count; + + public ServiceAndDataset() { + } + + public ServiceAndDataset(ClimateService climateService, Dataset dataset, long count) { + this.climateService = climateService; + this.dataset = dataset; + this.count = count; + } + + public ClimateService getClimateService() { + return climateService; + } + + public void setClimateService(ClimateService climateService) { + this.climateService = climateService; + } + + public Dataset getDataset() { + return dataset; + } + + public void setDataset(Dataset dataset) { + this.dataset = dataset; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public long getId() { + return id; + } + + @Override + public String toString() { + return "ServiceAndDataset [id=" + id + ", climateService=" + + climateService + ", dataset=" + dataset + ", count=" + count + + "]"; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/ServiceAndDatasetRepository.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/ServiceAndDatasetRepository.java b/ApacheCMDA_Backend_1.0/app/models/ServiceAndDatasetRepository.java new file mode 100644 index 0000000..14258b3 --- /dev/null +++ b/ApacheCMDA_Backend_1.0/app/models/ServiceAndDatasetRepository.java @@ -0,0 +1,18 @@ +package models; + +import java.util.List; + +import org.springframework.data.repository.CrudRepository; + +import javax.inject.Named; +import javax.inject.Singleton; + +@Named +@Singleton +public interface ServiceAndDatasetRepository extends CrudRepository<ServiceAndDataset, Long> { + + List<ServiceAndDataset> findByClimateService(ClimateService service); + List<ServiceAndDataset> findByDataset(Dataset dataset); + +} + http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/ServiceAndUser.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/ServiceAndUser.java b/ApacheCMDA_Backend_1.0/app/models/ServiceAndUser.java new file mode 100644 index 0000000..42806f0 --- /dev/null +++ b/ApacheCMDA_Backend_1.0/app/models/ServiceAndUser.java @@ -0,0 +1,69 @@ +package models; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; + +@Entity +public class ServiceAndUser { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private long id; + @ManyToOne(optional = false) + @JoinColumn(name = "userId", referencedColumnName = "id") + private User user; + @ManyToOne(optional = false) + @JoinColumn(name = "serviceId", referencedColumnName = "id") + private ClimateService climateService; + private long count; + + public ServiceAndUser() { + } + + public ServiceAndUser(User user, ClimateService climateService, long count) { + this.user = user; + this.climateService = climateService; + this.count = count; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + public long getCount() { + return count; + } + + public void setCount(long count) { + this.count = count; + } + + public ClimateService getClimateService() { + return climateService; + } + + @Override + public String toString() { + return "ServiceAndUser [id=" + id + ", user=" + user + + ", climateService=" + climateService + ", count=" + count + + "]"; + } + +} + http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/models/ServiceAndUserRepository.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/models/ServiceAndUserRepository.java b/ApacheCMDA_Backend_1.0/app/models/ServiceAndUserRepository.java new file mode 100644 index 0000000..4f1c960 --- /dev/null +++ b/ApacheCMDA_Backend_1.0/app/models/ServiceAndUserRepository.java @@ -0,0 +1,18 @@ +package models; + +import java.util.List; + +import org.springframework.data.repository.CrudRepository; + +import javax.inject.Named; +import javax.inject.Singleton; + +@Named +@Singleton +public interface ServiceAndUserRepository extends CrudRepository<ServiceAndUser, Long> { + + List<ServiceAndUser> findByUser(User user); + List<ServiceAndUser> findByClimateService(ClimateService service); + +} + http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/app/util/Matrix.java ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/app/util/Matrix.java b/ApacheCMDA_Backend_1.0/app/util/Matrix.java new file mode 100644 index 0000000..407ef04 --- /dev/null +++ b/ApacheCMDA_Backend_1.0/app/util/Matrix.java @@ -0,0 +1,234 @@ +package util; + +public class Matrix { + private final int M; // number of rows + private final int N; // number of columns + private final int[][] data; // M-by-N array + + // create M-by-N matrix of 0's + public Matrix(int M, int N) { + this.M = M; + this.N = N; + data = new int[M][N]; + } + + // create matrix based on 2d array + public Matrix(int[][] data) { + M = data.length; + N = data[0].length; + this.data = new int[M][N]; + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + this.data[i][j] = data[i][j]; + } + + // copy constructor + private Matrix(Matrix A) { + this(A.data); + } + + // create and return a random M-by-N matrix with values between 0 and 1 + // Change: A.data[i][j] = Math.random(); + public static Matrix random(int M, int N) { + Matrix A = new Matrix(M, N); + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + A.data[i][j] = (int) Math.random(); + return A; + } + + // create and return the N-by-N identity matrix + public static Matrix identity(int N) { + Matrix I = new Matrix(N, N); + for (int i = 0; i < N; i++) + I.data[i][i] = 1; + return I; + } + + // swap rows i and j + private void swap(int i, int j) { + int[] temp = data[i]; + data[i] = data[j]; + data[j] = temp; + } + + // create and return the transpose of the invoking matrix + public Matrix transpose() { + Matrix A = new Matrix(N, M); + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + A.data[j][i] = this.data[i][j]; + return A; + } + + // return C = A + B + public Matrix plus(Matrix B) { + Matrix A = this; + if (B.M != A.M || B.N != A.N) + throw new RuntimeException("Illegal matrix dimensions."); + Matrix C = new Matrix(M, N); + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + C.data[i][j] = A.data[i][j] + B.data[i][j]; + return C; + } + + // return C = A - B + public Matrix minus(Matrix B) { + Matrix A = this; + if (B.M != A.M || B.N != A.N) + throw new RuntimeException("Illegal matrix dimensions."); + Matrix C = new Matrix(M, N); + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + C.data[i][j] = A.data[i][j] - B.data[i][j]; + return C; + } + + // does A = B exactly? + public boolean eq(Matrix B) { + Matrix A = this; + if (B.M != A.M || B.N != A.N) + throw new RuntimeException("Illegal matrix dimensions."); + for (int i = 0; i < M; i++) + for (int j = 0; j < N; j++) + if (A.data[i][j] != B.data[i][j]) + return false; + return true; + } + + // return C = A * B + public Matrix times(Matrix B) { + Matrix A = this; + if (A.N != B.M) + throw new RuntimeException("Illegal matrix dimensions."); + Matrix C = new Matrix(A.M, B.N); + for (int i = 0; i < C.M; i++) + for (int j = 0; j < C.N; j++) + for (int k = 0; k < A.N; k++) + C.data[i][j] += (A.data[i][k] * B.data[k][j]); + return C; + } + + // return x = A^-1 b, assuming A is square and has full rank + // Cast (int) + public Matrix solve(Matrix rhs) { + if (M != N || rhs.M != N || rhs.N != 1) + throw new RuntimeException("Illegal matrix dimensions."); + + // create copies of the data + Matrix A = new Matrix(this); + Matrix b = new Matrix(rhs); + + // Gaussian elimination with partial pivoting + for (int i = 0; i < N; i++) { + + // find pivot row and swap + int max = i; + for (int j = i + 1; j < N; j++) + if (Math.abs(A.data[j][i]) > Math.abs(A.data[max][i])) + max = j; + A.swap(i, max); + b.swap(i, max); + + // singular + if (A.data[i][i] == 0) + throw new RuntimeException("Matrix is singular."); + + // pivot within b + for (int j = i + 1; j < N; j++) + b.data[j][0] -= b.data[i][0] * A.data[j][i] / A.data[i][i]; + + // pivot within A + for (int j = i + 1; j < N; j++) { + double m = A.data[j][i] / A.data[i][i]; + for (int k = i + 1; k < N; k++) { + A.data[j][k] -= A.data[i][k] * m; + } + A.data[j][i] = 0; + } + } + + // back substitution + Matrix x = new Matrix(N, 1); + for (int j = N - 1; j >= 0; j--) { + double t = 0.0; + for (int k = j + 1; k < N; k++) + t += A.data[j][k] * x.data[k][0]; + x.data[j][0] = (int) ((b.data[j][0] - t) / A.data[j][j]); + } + return x; + + } + + // print matrix to standard output + public void show() { + for (int i = 0; i < M; i++) { + for (int j = 0; j < N; j++) + System.out.printf("%d ", data[i][j]); + System.out.println(); + } + } + + // print matrix to standard output + public int[][] getArray() { + return data; + } + + // test client + public static void main(String[] args) { + int[][] d = { { 1, 2, 3 }, { 4, 5, 6 }, { 9, 1, 3 } }; + Matrix D = new Matrix(d); + D.show(); + System.out.println(); + + int[][] a = D.getArray(); + for(int[] i : a) { + for(int j : i) { + System.out.printf("%d ", j); + } + System.out.println(); + } + System.out.println(); + + + Matrix A = D; + A.show(); + System.out.println(); + + A.swap(1, 2); + A.show(); + System.out.println(); + + Matrix B = A.transpose(); + B.show(); + System.out.println(); + + Matrix C = Matrix.identity(5); + C.show(); + System.out.println(); + + A.plus(B).show(); + System.out.println(); + + B.times(A).show(); + System.out.println(); + + // shouldn't be equal since AB != BA in general + System.out.println(A.times(B).eq(B.times(A))); + System.out.println(); + + Matrix b = Matrix.random(5, 1); + b.show(); + System.out.println(); + + Matrix x = A.solve(b); + x.show(); + System.out.println(); + + A.times(x).show(); + + + + } +} http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/conf/.DS_Store ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/conf/.DS_Store b/ApacheCMDA_Backend_1.0/conf/.DS_Store new file mode 100644 index 0000000..c7bbec7 Binary files /dev/null and b/ApacheCMDA_Backend_1.0/conf/.DS_Store differ http://git-wip-us.apache.org/repos/asf/incubator-cmda/blob/d6e12b89/ApacheCMDA_Backend_1.0/conf/routes ---------------------------------------------------------------------- diff --git a/ApacheCMDA_Backend_1.0/conf/routes b/ApacheCMDA_Backend_1.0/conf/routes index b59bff7..3846661 100644 --- a/ApacheCMDA_Backend_1.0/conf/routes +++ b/ApacheCMDA_Backend_1.0/conf/routes @@ -15,6 +15,7 @@ GET /climateService/getAllMostRecentClimateServicesByLatestAccessTime/ GET /climateService/getAllMostUsedClimateServices/json @controllers.ClimateServiceController.getAllClimateServicesOrderByCount(format: String="json") GET /climateService/getTopKUsedClimateServicesByDatasetId/:id @controllers.ClimateServiceController.getTopKUsedClimateServicesByDatasetId(id: Long, format: String="json") POST /climateService/addClimateService @controllers.ClimateServiceController.addClimateService +POST /climateService/queryClimateService @controllers.ClimateServiceController.queryClimateServices GET /climateService/getAllServiceEntries/json @controllers.ClimateServiceController.getAllServiceEntries(format: String="json") POST /climateService/addServiceEntry @controllers.ClimateServiceController.addServiceEntry PUT /climateService/updateClimateService/id/:id @controllers.ClimateServiceController.updateClimateServiceById(id: Long) @@ -138,7 +139,16 @@ POST /users/isEmailExisted @controllers.UserController.isEma DELETE /users/delete/userName/:userName/password/:password @controllers.UserController.deleteUserByUserNameandPassword(userName: String, password: String) # Analytics -GET /analytics/getAllDatasetAndUserWithCount/json @controllers.AnalyticsController.getAllDatasetAndUserWithCount(format: String="json") +#GET /analytics/getAllDatasetAndUserWithCount/json @controllers.AnalyticsController.getAllDatasetAndUserWithCount(format: String="json") +#GET /analytics/getAllServiceAndUserWithCount/json @controllers.AnalyticsController.getAllServiceAndUserWithCount(format: String="json") +#GET /analytics/getAllServiceAndDatasetWithCount/json @controllers.AnalyticsController.getAllServiceAndDatasetWithCount(format: String="json") +GET /analytics/getOneUserWithAllDatasetAndCountByUserId/:id/json @controllers.AnalyticsController.getOneUserWithAllDatasetAndCount(id: Long, format: String="json") +GET /analytics/getOneDatasetWithAllDatasetAndCountByDatasetId/:id/json @controllers.AnalyticsController.getOneDatasetWithAllDatasetAndCount(id: Long, format: String="json") +GET /analytics/getOneUserWithAllServiceAndCountByUserId/:id/json @controllers.AnalyticsController.getOneUserWithAllServiceAndCount(id: Long, format: String="json") +GET /analytics/getOneServiceWithAllUserAndCountByServiceId/:id/json @controllers.AnalyticsController.getOneServiceWithAllUserAndCount(id: Long, format: String="json") +GET /analytics/getOneServiceWithAllDatasetAndCountByServiceId/:id/json @controllers.AnalyticsController.getOneServiceWithAllDatasetAndCount(id: Long, format: String="json") +GET /analytics/getOneDatasetWithAllServiceAndCountByDatasetId/:id/json @controllers.AnalyticsController.getOneDatasetWithAllServiceAndCount(id: Long, format: String="json") +POST /analytics/getRelationalKnowledgeGraph/json @controllers.AnalyticsController.getRelationalKnowledgeGraph(format: String="json") # Map static resources from the /public folder to the /assets URL path GET /assets/*file controllers.Assets.at(path="/public", file)