From 332ac9c1091d3290e72610b650fd87fe4a6dd632 Mon Sep 17 00:00:00 2001 From: Benjamin Gamard Date: Fri, 26 Jan 2018 11:26:34 +0100 Subject: [PATCH] #159: workflow db model --- .../core/constant/RouteStepTransition.java | 23 ++++ .../docs/core/constant/RouteStepType.java | 18 ++++ .../docs/core/dao/jpa/RouteModelDao.java | 61 +++++++++++ .../dao/jpa/criteria/AuditLogCriteria.java | 1 - .../dao/jpa/criteria/RouteModelCriteria.java | 10 ++ .../docs/core/dao/jpa/dto/RouteModelDto.java | 50 +++++++++ .../sismics/docs/core/model/jpa/Route.java | 52 +++++++++ .../docs/core/model/jpa/RouteModel.java | 102 ++++++++++++++++++ .../docs/core/model/jpa/RouteStep.java | 95 ++++++++++++++++ .../src/main/resources/config.properties | 2 +- .../resources/db/update/dbupdate-015-0.sql | 6 ++ docs-web/src/dev/resources/config.properties | 2 +- .../rest/resource/RouteModelResource.java | 67 ++++++++++++ docs-web/src/prod/resources/config.properties | 2 +- .../src/stress/resources/config.properties | 2 +- .../docs/rest/TestRouteModelResource.java | 35 ++++++ 16 files changed, 523 insertions(+), 5 deletions(-) create mode 100644 docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepTransition.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepType.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RouteModelDao.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/RouteModelCriteria.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RouteModelDto.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/model/jpa/Route.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteModel.java create mode 100644 docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteStep.java create mode 100644 docs-core/src/main/resources/db/update/dbupdate-015-0.sql create mode 100644 docs-web/src/main/java/com/sismics/docs/rest/resource/RouteModelResource.java create mode 100644 docs-web/src/test/java/com/sismics/docs/rest/TestRouteModelResource.java diff --git a/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepTransition.java b/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepTransition.java new file mode 100644 index 00000000..5298835b --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepTransition.java @@ -0,0 +1,23 @@ +package com.sismics.docs.core.constant; + +/** + * Route step transitions. + * + * @author bgamard + */ +public enum RouteStepTransition { + /** + * Route step approved. + */ + APPROVED, + + /** + * Route step rejected. + */ + REJECTED, + + /** + * Route step validated. + */ + VALIDATED +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepType.java b/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepType.java new file mode 100644 index 00000000..2476782e --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/constant/RouteStepType.java @@ -0,0 +1,18 @@ +package com.sismics.docs.core.constant; + +/** + * Route step types. + * + * @author bgamard + */ +public enum RouteStepType { + /** + * Approval step with 2 choices. + */ + APPROVE, + + /** + * Simple validation step, no possible choice. + */ + VALIDATE +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RouteModelDao.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RouteModelDao.java new file mode 100644 index 00000000..8efac321 --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/RouteModelDao.java @@ -0,0 +1,61 @@ +package com.sismics.docs.core.dao.jpa; + +import com.google.common.base.Joiner; +import com.sismics.docs.core.dao.jpa.criteria.RouteModelCriteria; +import com.sismics.docs.core.dao.jpa.dto.RouteModelDto; +import com.sismics.docs.core.util.jpa.QueryParam; +import com.sismics.docs.core.util.jpa.QueryUtil; +import com.sismics.docs.core.util.jpa.SortCriteria; + +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Route model DAO. + * + * @author bgamard + */ +public class RouteModelDao { + /** + * Returns the list of all route models. + * + * @param criteria Search criteria + * @param sortCriteria Sort criteria + * @return List of route models + */ + public List findByCriteria(RouteModelCriteria criteria, SortCriteria sortCriteria) { + Map parameterMap = new HashMap(); + List criteriaList = new ArrayList<>(); + + StringBuilder sb = new StringBuilder("select rm.RTM_ID_C c0, rm.RTM_NAME_C c1, rm.RTM_CREATEDATE_D c2"); + sb.append(" from T_ROUTE_MODEL rm "); + + // Add search criterias + criteriaList.add("rm.RTM_DELETEDATE_D is null"); + + if (!criteriaList.isEmpty()) { + sb.append(" where "); + sb.append(Joiner.on(" and ").join(criteriaList)); + } + + // Perform the search + QueryParam queryParam = QueryUtil.getSortedQueryParam(new QueryParam(sb.toString(), parameterMap), sortCriteria); + @SuppressWarnings("unchecked") + List l = QueryUtil.getNativeQuery(queryParam).getResultList(); + + // Assemble results + List dtoList = new ArrayList<>(); + for (Object[] o : l) { + int i = 0; + RouteModelDto dto = new RouteModelDto(); + dto.setId((String) o[i++]); + dto.setName((String) o[i++]); + dto.setCreateTimestamp(((Timestamp) o[i++]).getTime()); + dtoList.add(dto); + } + return dtoList; + } +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/AuditLogCriteria.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/AuditLogCriteria.java index 6c209d22..52f516bf 100644 --- a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/AuditLogCriteria.java +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/AuditLogCriteria.java @@ -1,7 +1,6 @@ package com.sismics.docs.core.dao.jpa.criteria; - /** * Audit log criteria. * diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/RouteModelCriteria.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/RouteModelCriteria.java new file mode 100644 index 00000000..7d4599ff --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/criteria/RouteModelCriteria.java @@ -0,0 +1,10 @@ +package com.sismics.docs.core.dao.jpa.criteria; + + +/** + * Route model criteria. + * + * @author bgamard + */ +public class RouteModelCriteria { +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RouteModelDto.java b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RouteModelDto.java new file mode 100644 index 00000000..4c3bf77f --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/dao/jpa/dto/RouteModelDto.java @@ -0,0 +1,50 @@ +package com.sismics.docs.core.dao.jpa.dto; + +/** + * Route model DTO. + * + * @author bgamard + */ +public class RouteModelDto { + /** + * Route model ID. + */ + private String id; + + /** + * Name. + */ + private String name; + + /** + * Creation date. + */ + private Long createTimestamp; + + public String getId() { + return id; + } + + public RouteModelDto setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RouteModelDto setName(String name) { + this.name = name; + return this; + } + + public Long getCreateTimestamp() { + return createTimestamp; + } + + public RouteModelDto setCreateTimestamp(Long createTimestamp) { + this.createTimestamp = createTimestamp; + return this; + } +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Route.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Route.java new file mode 100644 index 00000000..b71641bb --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/Route.java @@ -0,0 +1,52 @@ +package com.sismics.docs.core.model.jpa; + +import com.google.common.base.MoreObjects; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +/** + * Route. + * + * @author bgamard + */ +@Entity +@Table(name = "T_ROUTE") +public class Route { + /** + * Route ID. + */ + @Id + @Column(name = "RTE_ID_C", length = 36) + private String id; + + /** + * Document ID. + */ + @Column(name = "RTE_IDDOCUMENT_C", nullable = false, length = 36) + private String documentId; + + /** + * Creation date. + */ + @Column(name = "RTE_CREATEDATE_D", nullable = false) + private Date createDate; + + /** + * Deletion date. + */ + @Column(name = "RTE_DELETEDATE_D") + private Date deleteDate; + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("documentId", documentId) + .add("createDate", createDate) + .toString(); + } +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteModel.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteModel.java new file mode 100644 index 00000000..44959525 --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteModel.java @@ -0,0 +1,102 @@ +package com.sismics.docs.core.model.jpa; + +import com.google.common.base.MoreObjects; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import java.util.Date; + +/** + * Route model. + * + * @author bgamard + */ +@Entity +@Table(name = "T_ROUTE_MODEL") +public class RouteModel { + /** + * Route model ID. + */ + @Id + @Column(name = "RTM_ID_C", length = 36) + private String id; + + /** + * Name. + */ + @Column(name = "RTM_NAME_C", nullable = false, length = 50) + private String name; + + /** + * Data. + */ + @Column(name = "RTM_DATA_C", nullable = false, length = 5000) + private String data; + + /** + * Creation date. + */ + @Column(name = "RTM_CREATEDATE_D", nullable = false) + private Date createDate; + + /** + * Deletion date. + */ + @Column(name = "RTM_DELETEDATE_D") + private Date deleteDate; + + public String getId() { + return id; + } + + public RouteModel setId(String id) { + this.id = id; + return this; + } + + public String getName() { + return name; + } + + public RouteModel setName(String name) { + this.name = name; + return this; + } + + public String getData() { + return data; + } + + public RouteModel setData(String data) { + this.data = data; + return this; + } + + public Date getCreateDate() { + return createDate; + } + + public RouteModel setCreateDate(Date createDate) { + this.createDate = createDate; + return this; + } + + public Date getDeleteDate() { + return deleteDate; + } + + public RouteModel setDeleteDate(Date deleteDate) { + this.deleteDate = deleteDate; + return this; + } + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("name", name) + .toString(); + } +} diff --git a/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteStep.java b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteStep.java new file mode 100644 index 00000000..a7f34905 --- /dev/null +++ b/docs-core/src/main/java/com/sismics/docs/core/model/jpa/RouteStep.java @@ -0,0 +1,95 @@ +package com.sismics.docs.core.model.jpa; + +import com.google.common.base.MoreObjects; +import com.sismics.docs.core.constant.RouteStepTransition; +import com.sismics.docs.core.constant.RouteStepType; + +import javax.persistence.*; +import java.util.Date; + +/** + * Route step. + * + * @author bgamard + */ +@Entity +@Table(name = "T_ROUTE_STEP") +public class RouteStep { + /** + * Route step ID. + */ + @Id + @Column(name = "RTP_ID_C", length = 36) + private String id; + + /** + * Route ID. + */ + @Column(name = "RTP_IDROUTE_C", nullable = false, length = 36) + private String routeId; + + /** + * Name. + */ + @Column(name = "RTP_NAME_C", nullable = false, length = 200) + private String name; + + /** + * Type. + */ + @Column(name = "RTP_TYPE_C", nullable = false, length = 50) + @Enumerated(EnumType.STRING) + private RouteStepType type; + + /** + * Transition. + */ + @Column(name = "RTP_TRANSITION_C", length = 50) + @Enumerated(EnumType.STRING) + private RouteStepTransition transition; + + /** + * Target ID (user or group). + */ + @Column(name = "RTP_IDTARGET_C", nullable = false, length = 36) + private String targetId; + + /** + * Order. + */ + @Column(name = "RTP_ORDER_N", nullable = false) + private Integer order; + + /** + * Creation date. + */ + @Column(name = "RTP_CREATEDATE_D", nullable = false) + private Date createDate; + + /** + * End date. + */ + @Column(name = "RTP_ENDDATE_D") + private Date endDate; + + /** + * Deletion date. + */ + @Column(name = "RTP_DELETEDATE_D") + private Date deleteDate; + + @Override + public String toString() { + return MoreObjects.toStringHelper(this) + .add("id", id) + .add("routeId", routeId) + .add("name", name) + .add("type", type) + .add("transition", transition) + .add("targetId", targetId) + .add("order", order) + .add("createDate", createDate) + .add("endDate", endDate) + .toString(); + } +} diff --git a/docs-core/src/main/resources/config.properties b/docs-core/src/main/resources/config.properties index f1624659..a1d48290 100644 --- a/docs-core/src/main/resources/config.properties +++ b/docs-core/src/main/resources/config.properties @@ -1 +1 @@ -db.version=14 \ No newline at end of file +db.version=15 \ No newline at end of file diff --git a/docs-core/src/main/resources/db/update/dbupdate-015-0.sql b/docs-core/src/main/resources/db/update/dbupdate-015-0.sql new file mode 100644 index 00000000..2866d436 --- /dev/null +++ b/docs-core/src/main/resources/db/update/dbupdate-015-0.sql @@ -0,0 +1,6 @@ +create table T_ROUTE_MODEL ( RTM_ID_C varchar(36) not null, RTM_NAME_C varchar(50) not null, RTM_DATA_C varchar(5000) not null, RTM_CREATEDATE_D datetime not null, RTM_DELETEDATE_D datetime, primary key (RTM_ID_C) ); +create cached table T_ROUTE ( RTE_ID_C varchar(36) not null, RTE_IDDOCUMENT_C varchar(36) not null, RTE_CREATEDATE_D datetime not null, RTE_DELETEDATE_D datetime, primary key (RTE_ID_C) ); +create cached table T_ROUTE_STEP ( RTP_ID_C varchar(36) not null, RTP_IDROUTE_C varchar(36) not null, RTP_NAME_C varchar(200) not null, RTP_TYPE_C varchar(50) not null, RTP_TRANSITION_C varchar(50), RTP_IDTARGET_C varchar(36) not null, RTP_ORDER_N int not null, RTE_CREATEDATE_D datetime not null, RTP_ENDDATE_D datetime, RTP_DELETEDATE_D datetime, primary key (RTP_ID_C) );; +alter table T_ROUTE add constraint FK_RTE_IDDOCUMENT_C foreign key (RTE_IDDOCUMENT_C) references T_DOCUMENT (DOC_ID_C) on delete restrict on update restrict; +alter table T_ROUTE_STEP add constraint FK_RTP_IDROUTE_C foreign key (RTP_IDROUTE_C) references T_ROUTE (RTE_ID_C) on delete restrict on update restrict; +update T_CONFIG set CFG_VALUE_C = '15' where CFG_ID_C = 'DB_VERSION'; diff --git a/docs-web/src/dev/resources/config.properties b/docs-web/src/dev/resources/config.properties index 743723d1..c51c6ec6 100644 --- a/docs-web/src/dev/resources/config.properties +++ b/docs-web/src/dev/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=14 \ No newline at end of file +db.version=15 \ No newline at end of file diff --git a/docs-web/src/main/java/com/sismics/docs/rest/resource/RouteModelResource.java b/docs-web/src/main/java/com/sismics/docs/rest/resource/RouteModelResource.java new file mode 100644 index 00000000..48e1aa6f --- /dev/null +++ b/docs-web/src/main/java/com/sismics/docs/rest/resource/RouteModelResource.java @@ -0,0 +1,67 @@ +package com.sismics.docs.rest.resource; + +import com.sismics.docs.core.dao.jpa.RouteModelDao; +import com.sismics.docs.core.dao.jpa.criteria.RouteModelCriteria; +import com.sismics.docs.core.dao.jpa.dto.RouteModelDto; +import com.sismics.docs.core.util.jpa.SortCriteria; +import com.sismics.rest.exception.ForbiddenClientException; + +import javax.json.Json; +import javax.json.JsonArrayBuilder; +import javax.json.JsonObjectBuilder; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Response; +import java.util.List; + +/** + * Route model REST resources. + * + * @author bgamard + */ +@Path("/routemodel") +public class RouteModelResource extends BaseResource { + /** + * Returns the list of all route models. + * + * @api {get} /routemodel Get route models + * @apiName GetRouteModel + * @apiGroup RouteModel + * @apiParam {Number} sort_column Column index to sort on + * @apiParam {Boolean} asc If true, sort in ascending order + * @apiSuccess {Object[]} routemodels List of route models + * @apiSuccess {String} routemodels.id ID + * @apiSuccess {String} routemodels.name Name + * @apiSuccess {Number} routemodels.create_date Create date (timestamp) + * @apiError (client) ForbiddenError Access denied + * @apiPermission user + * @apiVersion 1.5.0 + * + * @return Response + */ + @GET + public Response list( + @QueryParam("sort_column") Integer sortColumn, + @QueryParam("asc") Boolean asc) { + if (!authenticate()) { + throw new ForbiddenClientException(); + } + + JsonArrayBuilder groups = Json.createArrayBuilder(); + SortCriteria sortCriteria = new SortCriteria(sortColumn, asc); + + RouteModelDao routeModelDao = new RouteModelDao(); + List routeModelDtoList = routeModelDao.findByCriteria(new RouteModelCriteria(), sortCriteria); + for (RouteModelDto routeModelDto : routeModelDtoList) { + groups.add(Json.createObjectBuilder() + .add("id", routeModelDto.getId()) + .add("name", routeModelDto.getName()) + .add("create_date", routeModelDto.getCreateTimestamp())); + } + + JsonObjectBuilder response = Json.createObjectBuilder() + .add("routemodels", groups); + return Response.ok().entity(response.build()).build(); + } +} diff --git a/docs-web/src/prod/resources/config.properties b/docs-web/src/prod/resources/config.properties index 743723d1..c51c6ec6 100644 --- a/docs-web/src/prod/resources/config.properties +++ b/docs-web/src/prod/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=14 \ No newline at end of file +db.version=15 \ No newline at end of file diff --git a/docs-web/src/stress/resources/config.properties b/docs-web/src/stress/resources/config.properties index 743723d1..c51c6ec6 100644 --- a/docs-web/src/stress/resources/config.properties +++ b/docs-web/src/stress/resources/config.properties @@ -1,3 +1,3 @@ api.current_version=${project.version} api.min_version=1.0 -db.version=14 \ No newline at end of file +db.version=15 \ No newline at end of file diff --git a/docs-web/src/test/java/com/sismics/docs/rest/TestRouteModelResource.java b/docs-web/src/test/java/com/sismics/docs/rest/TestRouteModelResource.java new file mode 100644 index 00000000..d866c564 --- /dev/null +++ b/docs-web/src/test/java/com/sismics/docs/rest/TestRouteModelResource.java @@ -0,0 +1,35 @@ +package com.sismics.docs.rest; + +import com.sismics.util.filter.TokenBasedSecurityFilter; +import org.junit.Assert; +import org.junit.Test; + +import javax.json.JsonArray; +import javax.json.JsonObject; + + +/** + * Test the route model resource. + * + * @author bgamard + */ +public class TestRouteModelResource extends BaseJerseyTest { + /** + * Test the route model resource. + */ + @Test + public void testRouteModelResource() { + // Login admin + String adminToken = clientUtil.login("admin", "admin", false); + + // Get all route models + JsonObject json = target().path("/routemodel") + .queryParam("sort_column", "1") + .queryParam("asc", "true") + .request() + .cookie(TokenBasedSecurityFilter.COOKIE_NAME, adminToken) + .get(JsonObject.class); + JsonArray groups = json.getJsonArray("routemodels"); + Assert.assertEquals(0, groups.size()); + } +} \ No newline at end of file