Optmiziations for the RESTful API managing containers of page models

Former-commit-id: 8472cb7e45
restapi
Jens Pelzetter 2020-08-06 16:21:30 +02:00
parent e5d05e998d
commit 429ceeea82
4 changed files with 95 additions and 42 deletions

View File

@ -18,6 +18,8 @@
*/ */
package org.libreccm.api.pagemodels; package org.libreccm.api.pagemodels;
import org.libreccm.api.dto.ListView;
import org.libreccm.api.pagemodels.dto.ContainerModelDto;
import org.libreccm.core.CoreConstants; import org.libreccm.core.CoreConstants;
import org.libreccm.pagemodel.ContainerModel; import org.libreccm.pagemodel.ContainerModel;
import org.libreccm.pagemodel.ContainerModelRepository; import org.libreccm.pagemodel.ContainerModelRepository;
@ -29,21 +31,20 @@ import org.libreccm.web.CcmApplication;
import java.net.URI; import java.net.URI;
import java.util.Optional; import java.util.Optional;
import java.util.stream.Collectors;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.inject.Inject; import javax.inject.Inject;
import javax.json.Json;
import javax.json.JsonArray;
import javax.json.JsonArrayBuilder;
import javax.json.JsonObject;
import javax.transaction.Transactional; import javax.transaction.Transactional;
import javax.ws.rs.Consumes; import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE; import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.PUT; import javax.ws.rs.PUT;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
@ -73,6 +74,8 @@ public class Containers {
* which the {@link PageModel} belongs. * which the {@link PageModel} belongs.
* @param pageModelName The name of the {@link PageModel} of which the * @param pageModelName The name of the {@link PageModel} of which the
* containers are retrieved. * containers are retrieved.
* @param limit
* @param offset
* *
* @return A JSON array containing the data of all {@link ContainerModel}s * @return A JSON array containing the data of all {@link ContainerModel}s
* of the {@link PageModel} identified by {@code pageModelName} of * of the {@link PageModel} identified by {@code pageModelName} of
@ -84,9 +87,11 @@ public class Containers {
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonArray getContainers( public ListView<ContainerModelDto> getContainers(
@PathParam("appName") final String appName, @PathParam("appName") final String appName,
@PathParam("pageModelName") final String pageModelName @PathParam("pageModelName") final String pageModelName,
@QueryParam("limit") @DefaultValue("20") final int limit,
@QueryParam("offset") @DefaultValue("0") final int offset
) { ) {
final CcmApplication app = controller.findCcmApplication( final CcmApplication app = controller.findCcmApplication(
String.format("/%s/", appName) String.format("/%s/", appName)
@ -96,14 +101,15 @@ public class Containers {
app, pageModelName app, pageModelName
); );
final JsonArrayBuilder arrayBuilder = Json.createArrayBuilder(); return new ListView<>(
pageModel containerModelRepo
.getContainers() .findContainersOfPageModelAsStream(pageModel, 0, 0)
.stream() .map(model -> new ContainerModelDto(model))
.map(containerModel -> mapContainerModelToJson(containerModel)) .collect(Collectors.toList()),
.forEach(arrayBuilder::add); containerModelRepo.countContainersOfPageModel(pageModel),
limit,
return arrayBuilder.build(); offset
);
} }
/** /**
@ -124,7 +130,7 @@ public class Containers {
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired @AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public JsonObject getContainer( public ContainerModelDto getContainer(
@PathParam("appName") final String appName, @PathParam("appName") final String appName,
@PathParam("pageModelName") final String pageModelName, @PathParam("pageModelName") final String pageModelName,
@PathParam("containerKey") final String containerKey @PathParam("containerKey") final String containerKey
@ -141,7 +147,7 @@ public class Containers {
app, pageModel, containerKey app, pageModel, containerKey
); );
return mapContainerModelToJson(container); return new ContainerModelDto(container);
} }
/** /**
@ -176,7 +182,7 @@ public class Containers {
@PathParam("appName") final String appName, @PathParam("appName") final String appName,
@PathParam("pageModelName") final String pageModelName, @PathParam("pageModelName") final String pageModelName,
@PathParam("containerKey") final String containerKey, @PathParam("containerKey") final String containerKey,
final JsonObject containerModelData final ContainerModelDto containerModelData
) { ) {
final CcmApplication app = controller.findCcmApplication( final CcmApplication app = controller.findCcmApplication(
String.format("/%s/", appName) String.format("/%s/", appName)
@ -277,25 +283,4 @@ public class Containers {
) )
).build(); ).build();
} }
/**
* Helper method for mapping a {@link ContainerModel} to JSON:
*
* @param containerModel The {@link ContainerModel} to map.
*
* @return A {@link JsonObject} containing the data of the
* {@link ContainerModel}.
*/
private JsonObject mapContainerModelToJson(
final ContainerModel containerModel) {
return Json
.createObjectBuilder()
.add("containerId", Long.toString(containerModel.getContainerId()))
.add("uuid", containerModel.getUuid())
.add("containerUuid", containerModel.getContainerUuid())
.add("key", containerModel.getKey())
.build();
}
} }

View File

@ -45,6 +45,14 @@ public class ContainerModelDto {
this.key = fromContainerModel.getKey(); this.key = fromContainerModel.getKey();
} }
public long getContainerId() {
return containerId;
}
public void setContainerId(final long containerId) {
this.containerId = containerId;
}
public String getUuid() { public String getUuid() {
return uuid; return uuid;
} }

View File

@ -59,10 +59,21 @@ import javax.xml.bind.annotation.XmlTransient;
@Entity @Entity
@Table(name = "PAGE_MODEL_CONTAINER_MODELS", schema = CoreConstants.DB_SCHEMA) @Table(name = "PAGE_MODEL_CONTAINER_MODELS", schema = CoreConstants.DB_SCHEMA)
@NamedQueries({ @NamedQueries({
@NamedQuery(name = "ContainerModel.findByKeyAndPage", @NamedQuery(
query = "SELECT c FROM ContainerModel c " name = "ContainerModel.findContainersOfPageModel",
+ "WHERE c.key = :key " query = "SELECT c FROM ContainerModel c WHERE c.pageModel = :pageModel"
+ "AND c.pageModel = :pageModel") ),
@NamedQuery(
name = "ContainerModel.countContainersOfPageModel",
query = "SELECT COUNT(c) FROM ContainerModel c "
+ "WHERE c.pageModel = :pageModel"
),
@NamedQuery(
name = "ContainerModel.findByKeyAndPage",
query = "SELECT c FROM ContainerModel c "
+ "WHERE c.key = :key "
+ "AND c.pageModel = :pageModel"
)
}) })
@XmlRootElement(name = "container-model") @XmlRootElement(name = "container-model")
public class ContainerModel implements Serializable { public class ContainerModel implements Serializable {

View File

@ -23,8 +23,10 @@ import org.libreccm.core.CoreConstants;
import org.libreccm.security.AuthorizationRequired; import org.libreccm.security.AuthorizationRequired;
import org.libreccm.security.RequiresPrivilege; import org.libreccm.security.RequiresPrivilege;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Stream;
import javax.enterprise.context.RequestScoped; import javax.enterprise.context.RequestScoped;
import javax.persistence.NoResultException; import javax.persistence.NoResultException;
@ -83,6 +85,53 @@ public class ContainerModelRepository
} }
} }
@Transactional(Transactional.TxType.REQUIRED)
public List<ContainerModel> findContainersOfPageModelAsList(
final PageModel pageModel,
final int limit,
final int offset
) {
return getEntityManager()
.createNamedQuery(
"ContainerModel.findContainersOfPageModel",
ContainerModel.class
)
.setParameter("pageModel", pageModel)
.setMaxResults(limit)
.setFirstResult(offset)
.getResultList();
}
@Transactional(Transactional.TxType.REQUIRED)
public Stream<ContainerModel> findContainersOfPageModelAsStream(
final PageModel pageModel,
final int limit,
final int offset
) {
return getEntityManager()
.createNamedQuery(
"ContainerModel.findContainersOfPageModel",
ContainerModel.class
)
.setParameter("pageModel", pageModel)
.setMaxResults(limit)
.setFirstResult(offset)
.getResultStream();
}
@Transactional(Transactional.TxType.REQUIRED)
public long countContainersOfPageModel(
final PageModel pageModel
) {
return getEntityManager()
.createNamedQuery(
"ContainerModel.countContainersOfPageModel",
Long.class
)
.setParameter("pageModel", pageModel)
.getSingleResult();
}
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public Optional<ContainerModel> findContainerByKeyAndPageModel( public Optional<ContainerModel> findContainerByKeyAndPageModel(
final String key, final PageModel pageModel) { final String key, final PageModel pageModel) {