Skip to content

Commit

Permalink
Merge branch 'release/2022-09'
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-gomes committed Oct 16, 2022
2 parents d1650f7 + ee293af commit 8b9434d
Show file tree
Hide file tree
Showing 733 changed files with 936,300 additions and 517 deletions.
2 changes: 2 additions & 0 deletions app/Module.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import config.MetamodelProvider;
import config.impl.JPAMetamodelProvider;
import dao.*;
import dao.impl.FlatSchemaDao;
import dao.impl.jpa.*;
import jackson.databind.ObjectMapperFactory;
import jackson.databind.impl.HibernateObjectMapperFactory;
Expand All @@ -45,5 +46,6 @@ protected void configure() {
bind(QueryDao.class).to(JpaQueryDao.class);
bind(BranchDao.class).to(JpaBranchDao.class);
bind(TagDao.class).to(JpaTagDao.class);
bind(SchemaDao.class).to(FlatSchemaDao.class);
}
}
90 changes: 56 additions & 34 deletions app/controllers/BaseController.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*
* SysML v2 REST/HTTP Pilot Implementation
* Copyright (C) 2020 InterCAX LLC
* Copyright (C) 2020 California Institute of Technology ("Caltech")
* Copyright (C) 2020 InterCAX LLC
* Copyright (C) 2020 California Institute of Technology ("Caltech")
* Copyright (C) 2022 Twingineer LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
Expand Down Expand Up @@ -37,67 +38,88 @@ public abstract class BaseController extends Controller {
protected static char CURSOR_SEPARATOR = '|';
protected static int DEFAULT_PAGE_SIZE = 100;

protected static UUID fromCursor(String cursor) throws IllegalArgumentException {
private static String stringFromCursor(String cursor) throws IllegalArgumentException {
byte[] decoded = Base64.getUrlDecoder().decode(cursor);
int separatorIndex = Bytes.indexOf(decoded, (byte) CURSOR_SEPARATOR);
if (separatorIndex < 0) {
throw new IllegalArgumentException("Provided cursor is malformed");
}
return UUID.fromString(
new String(decoded, separatorIndex + 1, decoded.length - separatorIndex - 1)
);
return new String(decoded, separatorIndex + 1, decoded.length - separatorIndex - 1);
}

protected static String toCursor(UUID id) throws IllegalArgumentException {
private static String stringToCursor(String string) {
String unencoded = String.valueOf(Instant.now().toEpochMilli()) +
CURSOR_SEPARATOR +
id.toString();
string;
return Base64.getUrlEncoder().withoutPadding().encodeToString(unencoded.getBytes());
}

protected static class PageRequest {
private final UUID after;
private final UUID before;
private static UUID uuidFromCursor(String cursor) throws IllegalArgumentException {
return UUID.fromString(stringFromCursor(cursor));
}

private static String uuidToCursor(UUID id) throws IllegalArgumentException {
return stringToCursor(id.toString());
}

protected static class PageRequest<T> {
private final T after;
private final T before;
private final int size;

private PageRequest(UUID after, UUID before, int size) {
private PageRequest(T after, T before, int size) {
if (size <= 0) {
throw new IllegalArgumentException("Page size must be greater than zero");
}

this.after = after;
this.before = before;
this.size = size;
}

public UUID getAfter() {
public T getAfter() {
return after;
}

public UUID getBefore() {
public T getBefore() {
return before;
}

public int getSize() {
return size;
}
}

protected static PageRequest from(Http.Request request) throws IllegalArgumentException {
UUID after = Optional.ofNullable(request.getQueryString("page[after]"))
.map(BaseController::fromCursor)
//.map(UUID::fromString)
.orElse(null);
UUID before = Optional.ofNullable(request.getQueryString("page[before]"))
.map(BaseController::fromCursor)
//.map(UUID::fromString)
.orElse(null);
int size = Optional.ofNullable(request.getQueryString("page[size]"))
.map(Integer::parseInt)
.orElse(DEFAULT_PAGE_SIZE);
if (size <= 0) {
throw new IllegalArgumentException("Page size must be greater than zero");
}
return new PageRequest(after, before, size);
}
protected static PageRequest<UUID> uuidRequest(Http.Request request) throws IllegalArgumentException {
return request(request, BaseController::uuidFromCursor);
}

protected static PageRequest<String> stringRequest(Http.Request request) throws IllegalArgumentException {
return request(request, BaseController::stringFromCursor);
}

private static <T> PageRequest<T> request(Http.Request request, Function<String, T> decoder) throws IllegalArgumentException {
T after = Optional.ofNullable(request.getQueryString("page[after]"))
.map(decoder)
.orElse(null);
T before = Optional.ofNullable(request.getQueryString("page[before]"))
.map(decoder)
.orElse(null);
int size = Optional.ofNullable(request.getQueryString("page[size]"))
.map(Integer::parseInt)
.orElse(DEFAULT_PAGE_SIZE);
return new PageRequest<>(after, before, size);
}

protected static Result uuidResponse(Result result, int resultSize, Function<Integer, UUID> idAtIndex, Http.Request request, PageRequest<UUID> pageRequest) {
return response(result, resultSize, idAtIndex, request, pageRequest, BaseController::uuidToCursor);
}

protected static Result stringResponse(Result result, int resultSize, Function<Integer, String> idAtIndex, Http.Request request, PageRequest<String> pageRequest) {
return response(result, resultSize, idAtIndex, request, pageRequest, BaseController::stringToCursor);
}

protected static Result paginateResult(Result result, int resultSize, Function<Integer, UUID> idAtIndex, Http.Request request, PageRequest pageRequest) {
private static <T> Result response(Result result, int resultSize, Function<Integer, T> idAtIndex, Http.Request request, PageRequest<T> pageRequest, Function<T, String> encoder) {
if (resultSize > 0) {
boolean pageFull = resultSize == pageRequest.getSize();
boolean hasNext = pageFull || pageRequest.getBefore() != null;
Expand All @@ -108,7 +130,7 @@ protected static Result paginateResult(Result result, int resultSize, Function<I
linkHeaderValueBuilder.append(String.format("<http://%s%s?page[after]=%s&page[size]=%s>; rel=\"next\"",
request.host(),
request.path(),
toCursor(idAtIndex.apply(resultSize - 1)),
encoder.apply(idAtIndex.apply(resultSize - 1)),
pageRequest.getSize()));
if (hasPrev) {
linkHeaderValueBuilder.append(", ");
Expand All @@ -118,7 +140,7 @@ protected static Result paginateResult(Result result, int resultSize, Function<I
linkHeaderValueBuilder.append(String.format("<http://%s%s?page[before]=%s&page[size]=%s>; rel=\"prev\"",
request.host(),
request.path(),
toCursor(idAtIndex.apply(0)),
encoder.apply(idAtIndex.apply(0)),
pageRequest.getSize()));
}
if (linkHeaderValueBuilder.length() > 0) {
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/BranchController.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,14 @@ public Result postBranchByProject(UUID projectId, Request request) {
}

public Result getBranchesByProject(UUID projectId, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Branch> branches = branchService.getByProjectId(
projectId,
pageRequest.getAfter(),
pageRequest.getBefore(),
pageRequest.getSize()
);
return paginateResult(
return uuidResponse(
buildResult(branches, List.class, metamodelProvider.getImplementationClass(Branch.class), request, new ProjectContainmentParameters(projectId)),
branches.size(),
idx -> branches.get(idx).getId(),
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/CommitController.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ private Result postCommitByProject(UUID projectId, @SuppressWarnings("OptionalUs
}

public Result getCommitsByProject(UUID projectId, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Commit> commits = commitService.getByProjectId(
projectId,
pageRequest.getAfter(),
Expand All @@ -105,7 +105,7 @@ public Result getCommitsByProject(UUID projectId, Request request) {
writer -> writer.withView(CommitImpl.Views.Compact.class)
);
Result result = buildResult(json, ld);
return paginateResult(
return uuidResponse(
result,
commits.size(),
idx -> commits.get(idx).getId(),
Expand Down
8 changes: 4 additions & 4 deletions app/controllers/ElementController.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public ElementController(ElementService elementService, MetamodelProvider metamo
}

public Result getElementsByProjectIdCommitId(UUID projectId, UUID commitId, Optional<Boolean> excludeUsed, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Element> elements = elementService.getElementsByProjectIdCommitId(projectId, commitId, excludeUsed.orElse(false), pageRequest.getAfter(), pageRequest.getBefore(), pageRequest.getSize());
return buildPaginatedResult(elements, projectId, commitId, request, pageRequest);
}
Expand All @@ -62,7 +62,7 @@ public Result getElementByProjectIdCommitIdElementId(UUID projectId, UUID commit
}

public Result getRootsByProjectIdCommitId(UUID projectId, UUID commitId, Optional<Boolean> excludeUsed, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Element> roots = elementService.getRootsByProjectIdCommitId(projectId, commitId, excludeUsed.orElse(false), pageRequest.getAfter(), pageRequest.getBefore(), pageRequest.getSize());
return buildPaginatedResult(roots, projectId, commitId, request, pageRequest);
}
Expand All @@ -72,8 +72,8 @@ public Result getElementByProjectIdCommitIdQualifiedName(UUID projectId, UUID co
return buildResult(element.orElse(null), request, new DataJsonLdAdorner.Parameters(projectId, commitId));
}

private Result buildPaginatedResult(List<Element> elements, UUID projectId, UUID commitId, Request request, PageRequest pageRequest) {
return paginateResult(
private Result buildPaginatedResult(List<Element> elements, UUID projectId, UUID commitId, Request request, PageRequest<UUID> pageRequest) {
return uuidResponse(
buildResult(elements, List.class, metamodelProvider.getImplementationClass(Element.class), request, new DataJsonLdAdorner.Parameters(projectId, commitId)),
elements.size(),
idx -> elements.get(idx).getElementId(),
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/ProjectController.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ public Result deleteProjectById(UUID id, Request request) {
}

public Result getProjects(Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Project> projects = projectService.getAll(pageRequest.getAfter(), pageRequest.getBefore(), pageRequest.getSize());
return paginateResult(
return uuidResponse(
buildResult(projects, List.class, metamodelProvider.getImplementationClass(Project.class), request, null),
projects.size(),
idx -> projects.get(idx).getId(),
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/QueryController.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ public Result postQueryByProject(UUID projectId, Request request) {
}

public Result getQueriesByProject(UUID projectId, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Query> queries = queryService.getByProjectId(projectId, pageRequest.getAfter(), pageRequest.getBefore(), pageRequest.getSize());
return Optional.of(queries)
.map(collection -> JacksonHelper.collectionToTree(collection, List.class, metamodelProvider.getImplementationClass(Query.class)))
.map(Results::ok)
.map(result -> paginateResult(
.map(result -> uuidResponse(
result,
queries.size(),
idx -> queries.get(idx).getId(),
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/RelationshipController.java
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public RelationshipController(RelationshipService relationshipService, Metamodel

@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
public Result getRelationshipsByProjectIdCommitIdRelatedElementId(UUID projectId, UUID commitId, UUID relatedElementId, Optional<String> direction, Optional<Boolean> excludeUsed, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
RelationshipDirection relationshipDirection = direction
.flatMap(d -> Arrays.stream(RelationshipDirection.values())
.filter(rd -> rd.toString().equalsIgnoreCase(d))
Expand All @@ -74,7 +74,7 @@ public Result getRelationshipsByProjectIdCommitIdRelatedElementId(UUID projectId
}

private Result buildPaginatedResult(List<Relationship> relationships, UUID projectId, UUID commitId, Request request, PageRequest pageRequest) {
return paginateResult(
return uuidResponse(
buildResult(relationships, List.class, metamodelProvider.getImplementationClass(Relationship.class), request, new DataJsonLdAdorner.Parameters(projectId, commitId)),
relationships.size(),
idx -> relationships.get(idx).getElementId(),
Expand Down
94 changes: 94 additions & 0 deletions app/controllers/SchemaController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* SysML v2 REST/HTTP Pilot Implementation
* Copyright (C) 2022 Twingineer LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* @license LGPL-3.0-or-later <http://spdx.org/licenses/LGPL-3.0-or-later>
*/

package controllers;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import jackson.jsonld.RecordAdorners.ProjectContainmentParameters;
import org.omg.sysml.lifecycle.Branch;
import play.libs.Json;
import play.mvc.Http.Request;
import play.mvc.Result;
import play.mvc.Results;
import services.SchemaService;

import javax.inject.Inject;
import java.util.*;

public class SchemaController extends BaseController {

private final SchemaService schemaService;

@Inject
public SchemaController(SchemaService schemaService) {
this.schemaService = schemaService;
}

public Result getSchemas(Request request) {
PageRequest<String> pageRequest = stringRequest(request);
List<JsonNode> schemas = schemaService.get(
pageRequest.getAfter(),
pageRequest.getBefore(),
pageRequest.getSize()
);
return stringResponse(
!schemas.isEmpty() ? Results.ok(format(schemas)) : Results.notFound(),
schemas.size(),
idx -> schemas.get(idx).path("$id").asText(null),
request,
pageRequest
);
}

public Result getSchemaById(String schemaId) {
Optional<JsonNode> schema = schemaService.getById(schemaId);
if (schema.isEmpty()) {
return Results.notFound();
}
return Results.ok(schema.get());
}

private JsonNode format(List<JsonNode> schemas) {
ObjectNode object = Json.mapper().createObjectNode();
String schemaValue = schemas.get(0).path("$schema").asText(null);
if (schemaValue != null) {
object.put("$schema", schemaValue);
}
ObjectNode defs = object.putObject("$defs");
for (JsonNode schema : schemas) {
String id = Objects.requireNonNull(schema.path("$id").asText(null));
ObjectNode schemaNode = defs.putObject(id);
Iterator<Map.Entry<String, JsonNode>> fieldIterator = schema.fields();
while (fieldIterator.hasNext()) {
Map.Entry<String, JsonNode> field = fieldIterator.next();
String fieldName = field.getKey();
switch (fieldName) {
case "$schema":
case "$defs":
break;
default:
schemaNode.put(fieldName, field.getValue());
}
}
}
return object;
}
}
4 changes: 2 additions & 2 deletions app/controllers/TagController.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,14 @@ public Result postTagByProject(UUID projectId, Request request) {
}

public Result getTagsByProject(UUID projectId, Request request) {
PageRequest pageRequest = PageRequest.from(request);
PageRequest<UUID> pageRequest = uuidRequest(request);
List<Tag> tags = tagService.getByProjectId(
projectId,
pageRequest.getAfter(),
pageRequest.getBefore(),
pageRequest.getSize()
);
return paginateResult(
return uuidResponse(
buildResult(tags, List.class, metamodelProvider.getImplementationClass(Tag.class), request, new ProjectContainmentParameters(projectId)),
tags.size(),
idx -> tags.get(idx).getId(),
Expand Down
Loading

0 comments on commit 8b9434d

Please sign in to comment.