Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#219] Add support for AdminRules to Rest Batch services - [#221] Add RuleLimits handling to Rule REST endpoint #220

Open
wants to merge 3 commits into
base: 3.5.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public enum ServiceName {
users,
groups,
instances,
rules
rules,
adminrules
}

public enum TypeName {
Expand Down Expand Up @@ -99,7 +100,8 @@ public void setCascade(Boolean cascade) {
@XmlElement(name="user", type=RESTInputUser.class),
@XmlElement(name="userGroup", type=RESTInputGroup.class),
@XmlElement(name="instance", type=RESTInputInstance.class),
@XmlElement(name="rule", type=RESTInputRule.class)
@XmlElement(name="rule", type=RESTInputRule.class),
@XmlElement(name="adminrule", type=RESTInputAdminRule.class),
})
public AbstractRESTPayload getPayload() {
return payload;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* @author Etj (etj at geo-solutions.it)
*/
@XmlRootElement(name = "adminrule")
@XmlType(name="Rule", propOrder={"position","grant","username","rolename","instance","workspace"})
@XmlType(name="AminRule", propOrder={"position","grant","username","rolename","instance","workspace"})
public class RESTInputAdminRule extends AbstractRESTPayload
{
private RESTRulePosition position;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* @author Etj (etj at geo-solutions.it)
*/
@XmlRootElement(name = "rule")
@XmlType(name="Rule", propOrder={"position","grant","username","rolename","instance","ipaddress","service","request","workspace","layer","constraints"})
@XmlType(name="Rule", propOrder={"position","grant","username","rolename","instance","ipaddress","service","request","workspace","layer","limits","constraints"})
public class RESTInputRule extends AbstractRESTPayload {

private RESTRulePosition position;
Expand All @@ -38,6 +38,8 @@ public class RESTInputRule extends AbstractRESTPayload {

private GrantType grant;

private RESTRuleLimits limits;

private RESTLayerConstraints constraints;

public RESTInputRule() {
Expand Down Expand Up @@ -118,6 +120,13 @@ public void setWorkspace(String workspace) {
}


public RESTRuleLimits getLimits() {
return limits;
}

public void setLimits(RESTRuleLimits limits) {
this.limits = limits;
}

public RESTLayerConstraints getConstraints() {
return constraints;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
* @author Etj (etj at geo-solutions.it)
*/
@XmlRootElement(name = "Rule")
@XmlType(propOrder={"id", "priority","grant","username","rolename","instance","ipaddress","service","request","workspace","layer","constraints"})
@XmlType(propOrder={"id", "priority","grant","username","rolename","instance","ipaddress","service","request","workspace","layer","limits","constraints"})
public class RESTOutputRule implements Serializable {

private Long id;
Expand All @@ -43,6 +43,8 @@ public class RESTOutputRule implements Serializable {

private RESTLayerConstraints constraints;

private RESTRuleLimits limits;

public RESTOutputRule() {
}

Expand Down Expand Up @@ -126,10 +128,18 @@ public RESTLayerConstraints getConstraints() {
return constraints;
}

public RESTRuleLimits getLimits() {
return limits;
}

public void setConstraints(RESTLayerConstraints constraints) {
this.constraints = constraints;
}

public void setLimits(RESTRuleLimits limits) {
this.limits = limits;
}

public Long getPriority() {
return priority;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/* (c) 2022 Open Source Geospatial Foundation - all rights reserved
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.geofence.services.rest.model;

import org.geoserver.geofence.core.model.enums.CatalogMode;
import org.geoserver.geofence.core.model.enums.SpatialFilterType;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;

@XmlRootElement(name = "Limits")
@XmlType(propOrder={"restrictedAreaWkt","spatialFilterType","catalogMode"})
public class RESTRuleLimits {

private String restrictedAreaWkt;
private SpatialFilterType spatialFilterType;
private CatalogMode catalogMode;

public String getRestrictedAreaWkt() {
return restrictedAreaWkt;
}

public void setRestrictedAreaWkt(String restrictedAreaWkt) {
this.restrictedAreaWkt = restrictedAreaWkt;
}

public SpatialFilterType getSpatialFilterType() {
return spatialFilterType;
}

public void setSpatialFilterType(SpatialFilterType spatialFilterType) {
this.spatialFilterType = spatialFilterType;
}

public CatalogMode getCatalogMode() {
return catalogMode;
}

public void setCatalogMode(CatalogMode catalogMode) {
this.catalogMode = catalogMode;
}

@Override
public String toString() {
return "RESTRuleLimits{" +
"restrictedAreaWkt='" + restrictedAreaWkt + '\'' +
", spatialFilterType=" + spatialFilterType +
", catalogMode=" + catalogMode +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package org.geoserver.geofence.services.rest.impl;

import org.geoserver.geofence.services.rest.RESTAdminRuleService;
import org.geoserver.geofence.services.rest.RESTBatchService;
import org.geoserver.geofence.services.rest.RESTGSInstanceService;
import org.geoserver.geofence.services.rest.RESTRuleService;
Expand All @@ -17,6 +18,7 @@
import org.geoserver.geofence.services.rest.exception.NotFoundRestEx;
import org.geoserver.geofence.services.rest.model.RESTBatch;
import org.geoserver.geofence.services.rest.model.RESTBatchOperation;
import org.geoserver.geofence.services.rest.model.RESTInputAdminRule;
import org.geoserver.geofence.services.rest.model.RESTInputGroup;
import org.geoserver.geofence.services.rest.model.RESTInputInstance;
import org.geoserver.geofence.services.rest.model.RESTInputRule;
Expand Down Expand Up @@ -53,6 +55,7 @@ public class RESTBatchServiceImpl
private RESTUserGroupService restUserGroupService;
private RESTGSInstanceService restInstanceService;
private RESTRuleService restRuleService;
private RESTAdminRuleService restAdminRuleService;

@Transactional(value="geofenceTransactionManager")
@Override
Expand Down Expand Up @@ -90,6 +93,10 @@ public void runBatch(RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, I
dispatchRuleOp(op);
break;

case adminrules:
dispatchAdminRuleOp(op);
break;

default:
throw new BadRequestRestEx("Unhandled service for operation " + op);
}
Expand Down Expand Up @@ -237,6 +244,33 @@ else if(op.getId() != null)
}
}

protected void dispatchAdminRuleOp(RESTBatchOperation op) throws NotFoundRestEx, BadRequestRestEx {
switch (op.getType()) {
case insert:
ensurePayload(op);
restAdminRuleService.insert((RESTInputAdminRule) op.getPayload());
break;

case update:
ensurePayload(op);
if (op.getId() != null)
restAdminRuleService.update(op.getId(), (RESTInputAdminRule) op.getPayload());
else
throw new BadRequestRestEx("Missing identifier for op " + op);
break;

case delete:
if (op.getId() != null)
restAdminRuleService.delete(op.getId());
else
throw new BadRequestRestEx("Missing identifier for op " + op);
break;

default:
throw new BadRequestRestEx("Operation not bound " + op);
}
}

// ==========================================================================

private void ensurePayload(RESTBatchOperation op) throws BadRequestRestEx {
Expand Down Expand Up @@ -273,4 +307,7 @@ public void setRestUserService(RESTUserService restUserService) {
this.restUserService = restUserService;
}

public void setRestAdminRuleService(RESTAdminRuleService restAdminRuleService) {
this.restAdminRuleService = restAdminRuleService;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,19 @@

package org.geoserver.geofence.services.rest.impl;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;


import org.apache.commons.lang.StringUtils;

import org.geoserver.geofence.core.model.RuleLimits;
import org.geoserver.geofence.services.rest.model.RESTRuleLimits;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.MultiPolygon;
import org.locationtech.jts.io.ParseException;
Expand Down Expand Up @@ -55,6 +59,7 @@
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Collectors;

/**
*
Expand Down Expand Up @@ -88,7 +93,6 @@ public RESTOutputRule get(Long id) throws BadRequestRestEx, NotFoundRestEx, Inte
}

@Override
@Transactional(propagation = Propagation.REQUIRED, value = "geofenceTransactionManager")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not remove the Transactional annotation here: there are many db calls and race conditions may disrupt the priority handling.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

public Response insert(RESTInputRule inputRule) throws NotFoundRestEx, BadRequestRestEx, InternalErrorRestEx {

if (inputRule.getPosition() == null || inputRule.getPosition().getPosition() == null) {
Expand All @@ -115,6 +119,11 @@ public Response insert(RESTInputRule inputRule) throws NotFoundRestEx, BadReques
ruleAdminService.setDetails(id, details);
}

RuleLimits limits=limitsFromInput(inputRule.getLimits());
if (limits!=null) {
ruleAdminService.setLimits(id,limits);
}

return Response.status(Status.CREATED).tag(id.toString()).entity(id).build();
} catch (BadRequestServiceEx ex) {
LOGGER.error(ex.getMessage());
Expand All @@ -125,6 +134,13 @@ public Response insert(RESTInputRule inputRule) throws NotFoundRestEx, BadReques
}
}

private InsertPosition insertPosition(RESTInputRule inputRule){
return
inputRule.getPosition().getPosition() == RulePosition.fixedPriority ? InsertPosition.FIXED
: inputRule.getPosition().getPosition() == RulePosition.offsetFromBottom ? InsertPosition.FROM_END
: inputRule.getPosition().getPosition() == RulePosition.offsetFromTop ? InsertPosition.FROM_START : null;
}

@Override
public void update(Long id, RESTInputRule rule) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx {

Expand Down Expand Up @@ -579,6 +595,25 @@ protected RESTOutputRule toOutput(Rule rule) {
out.setConstraints(constraints);
}

if (rule.getRuleLimits()!=null){
RESTRuleLimits ruleLimits=new RESTRuleLimits();
RuleLimits limits=rule.getRuleLimits();
if (limits.getSpatialFilterType()!=null)
ruleLimits.setSpatialFilterType(limits.getSpatialFilterType());
if (limits.getCatalogMode()!=null)
ruleLimits.setCatalogMode(limits.getCatalogMode());
if (limits.getAllowedArea()!=null) {
MultiPolygon area = limits.getAllowedArea();
if (area != null) {
String areaWKT = "SRID=" + area.getSRID() + ";" + area.toText();
ruleLimits.setRestrictedAreaWkt(areaWKT);
}
if (limits.getSpatialFilterType()!=null)
ruleLimits.setSpatialFilterType(limits.getSpatialFilterType());
}
out.setLimits(ruleLimits);
}

return out;
}

Expand Down Expand Up @@ -608,6 +643,28 @@ protected Rule fromInput(RESTInputRule in) {
return rule;
}

protected RuleLimits limitsFromInput(RESTRuleLimits in){
RuleLimits limits=null;
if (in!=null && (in.getCatalogMode()!=null || in.getRestrictedAreaWkt()!=null)){
limits=new RuleLimits();
limits.setCatalogMode(in.getCatalogMode());
limits.setSpatialFilterType(in.getSpatialFilterType());
if (StringUtils.isNotBlank(in.getRestrictedAreaWkt())) {
if (in.getRestrictedAreaWkt() != null) {
Geometry g;
try {
g = toGeometryAllowedArea(in.getRestrictedAreaWkt());
} catch (ParseException ex) {
throw new BadRequestRestEx("Error parsing WKT:" + ex.getMessage());
}
limits.setAllowedArea((MultiPolygon) g);
}
}
}
return limits;
}


protected LayerDetails detailsFromInput(RESTInputRule in) {
RESTLayerConstraints constraints = in.getConstraints();
if (constraints != null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

import org.geoserver.geofence.services.RuleAdminService;
import org.geoserver.geofence.services.dto.ShortGroup;
import org.geoserver.geofence.services.rest.RESTAdminRuleService;
import org.geoserver.geofence.services.rest.RESTBatchService;
import org.geoserver.geofence.services.rest.RESTRuleService;
import org.geoserver.geofence.services.rest.RESTUserGroupService;
import org.geoserver.geofence.services.rest.RESTUserService;
Expand Down Expand Up @@ -39,6 +41,8 @@ public abstract class RESTBaseTest {
protected static RESTUserService restUserService;
protected static RESTUserGroupService restUserGroupService;
protected static RESTRuleService restRuleService;
protected static RESTAdminRuleService restAdminRuleService;
protected static RESTBatchService restBatchService;

public RESTBaseTest() {

Expand All @@ -59,11 +63,15 @@ public RESTBaseTest() {
restUserService = (RESTUserService)ctx.getBean("restUserService");
restUserGroupService = (RESTUserGroupService)ctx.getBean("restUserGroupService");
restRuleService = (RESTRuleService)ctx.getBean("restRuleService");
restAdminRuleService = (RESTAdminRuleService)ctx.getBean("restAdminRuleService");
restBatchService = (RESTBatchService) ctx.getBean("restBatchService");
}

assertNotNull(restUserService);
assertNotNull(restUserGroupService);
assertNotNull(restRuleService);
assertNotNull(restAdminRuleService);
assertNotNull(restBatchService);
}
}

Expand Down
Loading