diff --git a/src/core/model-external/pom.xml b/src/core/model-external/pom.xml index 4b6e56a3..bb833f3d 100644 --- a/src/core/model-external/pom.xml +++ b/src/core/model-external/pom.xml @@ -125,7 +125,14 @@ - + + + + + + + + diff --git a/src/core/model/src/main/java/org/geoserver/geofence/core/model/GSUser.java b/src/core/model/src/main/java/org/geoserver/geofence/core/model/GSUser.java index 79802ee4..d0145159 100644 --- a/src/core/model/src/main/java/org/geoserver/geofence/core/model/GSUser.java +++ b/src/core/model/src/main/java/org/geoserver/geofence/core/model/GSUser.java @@ -14,8 +14,10 @@ import java.util.Set; import javax.persistence.Column; +import javax.persistence.ConstraintMode; import javax.persistence.Entity; import javax.persistence.FetchType; +import javax.persistence.ForeignKey; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; @@ -34,7 +36,7 @@ import org.hibernate.annotations.CacheConcurrencyStrategy; import org.hibernate.annotations.Fetch; import org.hibernate.annotations.FetchMode; -import org.hibernate.annotations.ForeignKey; +//import org.hibernate.annotations.ForeignKey; import org.hibernate.annotations.Index; /** @@ -98,9 +100,11 @@ public class GSUser implements Identifiable, Serializable { /** Groups to which the user is associated */ @ManyToMany(fetch= FetchType.LAZY) - @JoinTable( name = "gf_user_usergroups", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns=@JoinColumn(name = "group_id") ) + @JoinTable( name = "gf_user_usergroups", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns=@JoinColumn(name = "group_id"), + foreignKey = @ForeignKey(name="fk_uug_user") ) @Column(name = "u_id") - @ForeignKey(name="fk_uug_user", inverseName="fk_uug_group") @Fetch(FetchMode.SUBSELECT) // without this, hibernate will duplicate results(!) private Set userGroups = new HashSet(); diff --git a/src/core/webtest/pom.xml b/src/core/webtest/pom.xml index 9d4ddf0b..7f81c3ce 100644 --- a/src/core/webtest/pom.xml +++ b/src/core/webtest/pom.xml @@ -57,6 +57,15 @@ geofence-services-impl + + org.geoserver.geofence + geofence-rest-api + + + org.geoserver.geofence + geofence-rest-impl + + @@ -103,19 +112,13 @@ - + org.codehaus.jettison jettison - javax.servlet javax.servlet-api @@ -123,56 +126,16 @@ provided - - + - - + javax.xml.ws jaxws-api - - - - org.apache.cxf - cxf-rt-transports-http - - - org.apache.cxf - cxf-rt-transports-http-jetty - - - org.apache.cxf - cxf-rt-frontend-jaxws - - - org.apache.cxf - cxf-rt-frontend-jaxrs - - - - org.apache.cxf - cxf-rt-bindings-soap - - - org.apache.cxf - cxf-rt-databinding-aegis - - - org.apache.cxf - cxf-rt-ws-security - @@ -180,13 +143,6 @@ - - org.springframework spring-beans @@ -207,10 +163,6 @@ org.springframework spring-tx - org.springframework spring-orm @@ -228,34 +180,6 @@ spring-webmvc - - - - - - - @@ -302,27 +226,9 @@ - - + - geofence-web-test + geofence-web-test diff --git a/src/core/webtest/src/main/java/org/geoserver/geofence/servicetest/MainTest.java b/src/core/webtest/src/main/java/org/geoserver/geofence/servicetest/MainTest.java index 0256c73a..dc728ff0 100644 --- a/src/core/webtest/src/main/java/org/geoserver/geofence/servicetest/MainTest.java +++ b/src/core/webtest/src/main/java/org/geoserver/geofence/servicetest/MainTest.java @@ -41,21 +41,30 @@ import org.geoserver.geofence.services.dto.RuleFilter; import org.geoserver.geofence.services.dto.RuleFilter.SpecialFilterType; import org.geoserver.geofence.services.exception.NotFoundServiceEx; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** * * @author ETj (etj at geo-solutions.it) */ +@Service public class MainTest implements InitializingBean, ApplicationContextAware { private final static Logger LOGGER = LogManager.getLogger(MainTest.class); + @Autowired private XmlWebApplicationContext applicationContext; + @Autowired private UserAdminService userAdminService; + @Autowired private UserGroupAdminService userGroupAdminService; + @Autowired private InstanceAdminService instanceAdminService; + @Autowired private RuleAdminService ruleAdminService; + @Autowired private RuleReaderService ruleReaderService; protected final static String MULTIPOLYGONWKT = "MULTIPOLYGON(((48 62, 48 63, 49 63, 49 62, 48 62)))"; @@ -292,31 +301,30 @@ protected void removeAllInstances() throws NotFoundServiceEx { //========================================================================== - public void setInstanceAdminService(InstanceAdminService instanceAdminService) { - this.instanceAdminService = instanceAdminService; - } - - public void setUserGroupAdminService(UserGroupAdminService userGroupAdminService) { - this.userGroupAdminService = userGroupAdminService; - } - - public void setRuleAdminService(RuleAdminService ruleAdminService) { - this.ruleAdminService = ruleAdminService; - } - - public void setUserAdminService(UserAdminService userAdminService) { - this.userAdminService = userAdminService; - } - - public void setRuleReaderService(RuleReaderService ruleReaderService) { - this.ruleReaderService = ruleReaderService; - } - - +// public void setInstanceAdminService(InstanceAdminService instanceAdminService) { +// this.instanceAdminService = instanceAdminService; +// } +// +// public void setUserGroupAdminService(UserGroupAdminService userGroupAdminService) { +// this.userGroupAdminService = userGroupAdminService; +// } +// +// public void setRuleAdminService(RuleAdminService ruleAdminService) { +// this.ruleAdminService = ruleAdminService; +// } +// +// public void setUserAdminService(UserAdminService userAdminService) { +// this.userAdminService = userAdminService; +// } +// +// public void setRuleReaderService(RuleReaderService ruleReaderService) { +// this.ruleReaderService = ruleReaderService; +// } +// +// @Override public void setApplicationContext(ApplicationContext ac) throws BeansException { this.applicationContext = (XmlWebApplicationContext)ac; - } } diff --git a/src/core/webtest/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/src/core/webtest/src/main/resources/META-INF/cxf/org.apache.cxf.Logger deleted file mode 100644 index 4fd93725..00000000 --- a/src/core/webtest/src/main/resources/META-INF/cxf/org.apache.cxf.Logger +++ /dev/null @@ -1 +0,0 @@ -org.apache.cxf.common.logging.Log4jLogger diff --git a/src/core/webtest/src/main/resources/applicationContext.xml b/src/core/webtest/src/main/resources/applicationContext.xml index bb99cf33..7d6ca1d4 100644 --- a/src/core/webtest/src/main/resources/applicationContext.xml +++ b/src/core/webtest/src/main/resources/applicationContext.xml @@ -5,47 +5,35 @@ */ --> + + - + - - - - - - - - - - \ No newline at end of file diff --git a/src/core/webtest/src/main/resources/geofence-datasource-ovr.properties b/src/core/webtest/src/main/resources/geofence-datasource-ovr.properties index 1908d3e0..80f7aa1b 100644 --- a/src/core/webtest/src/main/resources/geofence-datasource-ovr.properties +++ b/src/core/webtest/src/main/resources/geofence-datasource-ovr.properties @@ -3,6 +3,6 @@ # * application directory. # */ # -geofenceEntityManagerFactory.jpaPropertyMap[hibernate.hbm2ddl.auto]=create-drop +geofenceEntityManagerFactory.jpaPropertyMap[hibernate.hbm2ddl.auto]=create geofenceVendorAdapter.generateDdl=true geofenceVendorAdapter.showSql=false diff --git a/src/core/webtest/src/main/resources/log4j.xml b/src/core/webtest/src/main/resources/log4j.xml index ea73efad..fa467c70 100644 --- a/src/core/webtest/src/main/resources/log4j.xml +++ b/src/core/webtest/src/main/resources/log4j.xml @@ -39,14 +39,17 @@ --> - - - + + + + + + diff --git a/src/core/webtest/src/main/webapp/WEB-INF/remoting-servlet.xml b/src/core/webtest/src/main/webapp/WEB-INF/remoting-servlet.xml index 37119321..985a3598 100644 --- a/src/core/webtest/src/main/webapp/WEB-INF/remoting-servlet.xml +++ b/src/core/webtest/src/main/webapp/WEB-INF/remoting-servlet.xml @@ -11,15 +11,8 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" - xmlns:cxf="http://cxf.apache.org/core" - xmlns:jaxws="http://cxf.apache.org/jaxws" - xmlns:jaxrs="http://cxf.apache.org/jaxrs" - xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd - http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd - http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd - http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" default-autowire="byName"> diff --git a/src/core/webtest/src/main/webapp/WEB-INF/rest-servlet.xml b/src/core/webtest/src/main/webapp/WEB-INF/rest-servlet.xml new file mode 100644 index 00000000..e012ca18 --- /dev/null +++ b/src/core/webtest/src/main/webapp/WEB-INF/rest-servlet.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/src/core/webtest/src/main/webapp/WEB-INF/web.xml b/src/core/webtest/src/main/webapp/WEB-INF/web.xml index e636061c..47f6931e 100755 --- a/src/core/webtest/src/main/webapp/WEB-INF/web.xml +++ b/src/core/webtest/src/main/webapp/WEB-INF/web.xml @@ -4,46 +4,29 @@ * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ - - --> - + - - - contextConfigLocation - classpath*:applicationContext.xml - + + + contextConfigLocation + classpath*:applicationContext.xml + log4jConfiguration log4j.xml - - - org.springframework.web.context.ContextLoaderListener - - - - CXFServlet - org.apache.cxf.transport.servlet.CXFServlet - - - - CXFServlet - /serv/* - + remoting org.springframework.web.servlet.DispatcherServlet @@ -55,9 +38,21 @@ /remoting/* - - - Application.html - + + + rest + org.springframework.web.servlet.DispatcherServlet + 1 + + + + rest + /rest/* + + + + diff --git a/src/extension/rest/api/pom.xml b/src/extension/rest/api/pom.xml index 55a9bd5f..f62445ed 100644 --- a/src/extension/rest/api/pom.xml +++ b/src/extension/rest/api/pom.xml @@ -44,29 +44,40 @@ - + + + - + - - + junit junit test + + org.springframework + spring-web + 5.1.1.RELEASE + jar + diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTAdminRuleService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTAdminRuleService.java index 13fcad54..b509573b 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTAdminRuleService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTAdminRuleService.java @@ -9,91 +9,95 @@ import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; import org.geoserver.geofence.services.rest.model.RESTInputAdminRule; import org.geoserver.geofence.services.rest.model.RESTOutputAdminRule; import org.geoserver.geofence.services.rest.model.RESTOutputAdminRuleList; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") +@RequestMapping(path = "/adminrules") public interface RESTAdminRuleService { - @POST - @Path("/") - @Produces(MediaType.APPLICATION_XML) - Response insert(@Multipart("rule") RESTInputAdminRule rule) throws BadRequestRestEx, NotFoundRestEx; - - @GET - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - RESTOutputAdminRule get(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx; - - @PUT - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - void update(@PathParam("id") Long id, - @Multipart("rule") RESTInputAdminRule rule) throws BadRequestRestEx, NotFoundRestEx; - - @DELETE - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - Response delete(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx; - - @GET - @Path("/") - @Produces(MediaType.APPLICATION_XML) + @PostMapping( // + path = "/", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + ResponseEntity insert(@RequestBody RESTInputAdminRule rule) throws BadRequestRestEx, NotFoundRestEx; + + @GetMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTOutputAdminRule get(@PathVariable("id") Long id) throws BadRequestRestEx, NotFoundRestEx; + + @PutMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void update(@PathVariable("id") Long id, + @RequestBody RESTInputAdminRule rule) throws BadRequestRestEx, NotFoundRestEx; + + @DeleteMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + ResponseEntity delete(@PathVariable("id") Long id) throws BadRequestRestEx, NotFoundRestEx; + + @GetMapping( // + path = "/", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTOutputAdminRuleList get( - @QueryParam("page") Integer page, - @QueryParam("entries") Integer entries, - @QueryParam("full")@DefaultValue("false") boolean full, + @RequestParam("page") Integer page, + @RequestParam("entries") Integer entries, + @RequestParam(name="full", defaultValue = "false") boolean full, - @QueryParam("userName") String userName, - @QueryParam("userAny") Boolean userAny, + @RequestParam("userName") String userName, + @RequestParam("userAny") Boolean userAny, - @QueryParam("groupName") String groupName, - @QueryParam("groupAny") Boolean groupAny, + @RequestParam("groupName") String groupName, + @RequestParam("groupAny") Boolean groupAny, - @QueryParam("instanceId") Long instanceId, - @QueryParam("instanceName") String instanceName, - @QueryParam("instanceAny") Boolean instanceAny, + @RequestParam("instanceId") Long instanceId, + @RequestParam("instanceName") String instanceName, + @RequestParam("instanceAny") Boolean instanceAny, - @QueryParam("workspace") String workspace, - @QueryParam("workspaceAny") Boolean workspaceAny + @RequestParam("workspace") String workspace, + @RequestParam("workspaceAny") Boolean workspaceAny ) throws BadRequestRestEx, InternalErrorRestEx; - @GET - @Path("/count") + @GetMapping( // + path = "/count" + ) long count( - @QueryParam("userName") String userName, - @QueryParam("userAny") Boolean userAny, + @RequestParam("userName") String userName, + @RequestParam("userAny") Boolean userAny, - @QueryParam("groupName") String groupName, - @QueryParam("groupAny") Boolean groupAny, + @RequestParam("groupName") String groupName, + @RequestParam("groupAny") Boolean groupAny, - @QueryParam("instanceId") Long instanceId, - @QueryParam("instanceName") String instanceName, - @QueryParam("instanceAny") Boolean instanceAny, + @RequestParam("instanceId") Long instanceId, + @RequestParam("instanceName") String instanceName, + @RequestParam("instanceAny") Boolean instanceAny, - @QueryParam("workspace") String workspace, - @QueryParam("workspaceAny") Boolean workspaceAny + @RequestParam("workspace") String workspace, + @RequestParam("workspaceAny") Boolean workspaceAny ); } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTBatchService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTBatchService.java index ba28f857..61173541 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTBatchService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTBatchService.java @@ -10,27 +10,26 @@ import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; import org.geoserver.geofence.services.rest.model.RESTBatch; -import javax.ws.rs.Consumes; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") +@RequestMapping("/batch") public interface RESTBatchService { - @POST - @Path("/exec") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - Response exec(@Multipart("batch")RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + @PostMapping( // + path = "/exec", // + consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE} + ) + ResponseEntity exec(@RequestBody RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** * Similar to exec, but not transaction. diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTConfigService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTConfigService.java index 9769f8ab..ab85e52b 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTConfigService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTConfigService.java @@ -5,7 +5,6 @@ package org.geoserver.geofence.services.rest; - import org.geoserver.geofence.services.rest.exception.BadRequestRestEx; import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; @@ -18,145 +17,165 @@ import org.geoserver.geofence.services.rest.model.config.RESTFullUserGroupList; import org.geoserver.geofence.services.rest.model.config.RESTFullUserList; -import javax.ws.rs.Consumes; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") +@RequestMapping(path = "/service") public interface RESTConfigService { /** - * @deprecated misbehaves since usergroups introduction. Please use backup() + * @Deprecated misbehaves since usergroups introduction. Please use backup() */ - @GET - @Path("/full") - @Produces(MediaType.APPLICATION_XML) - RESTFullConfiguration getConfiguration(@QueryParam("includeGFUsers") - @DefaultValue("False") - Boolean includeGRUsers); - - @GET - @Path("/backup") - @Produces(MediaType.APPLICATION_XML) - RESTBatch backup(@QueryParam("includeGFUsers") - @DefaultValue("False") - Boolean includeGRUsers); - - @PUT - @Path("/restore") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - void restore(@Multipart("batch")RESTBatch batch) + @GetMapping( // + path = "/full", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTFullConfiguration getConfiguration( + @RequestParam(name = "includeGFUsers", defaultValue = "False") Boolean includeGRUsers); + + @GetMapping( // + path = "/backup", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTBatch backup( + @RequestParam(name = "includeGFUsers", defaultValue = "False") Boolean includeGRUsers); + + @PutMapping( // + path = "/restore", // + consumes = {MediaType.APPLICATION_XML_VALUE, MediaType.TEXT_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void restore(@RequestBody RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - @PUT - @Path("/cleanup") + @PutMapping( // + path = "/cleanup" + ) void cleanup() throws InternalErrorRestEx; - @GET - @Path("/backup/groups") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/backup/groups", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTBatch backupGroups(); - @GET - @Path("/backup/users") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/backup/users", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTBatch backupUsers(); - @GET - @Path("/backup/instances") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/backup/instances", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTBatch backupInstances(); - @GET - @Path("/backup/rules") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/backup/rules", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTBatch backupRules(); /** - * @deprecated + * @Deprecated */ - @PUT - @Path("/full") - @Produces(MediaType.APPLICATION_XML) - RESTConfigurationRemapping setConfiguration(@Multipart("configuration") RESTFullConfiguration config, - @QueryParam("includeGRUsers") - @DefaultValue("False") - Boolean includeGRUsers) + @PutMapping( // + path = "/full", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTConfigurationRemapping setConfiguration( + @RequestBody RESTFullConfiguration config, + @RequestParam(name = "includeGRUsers", defaultValue = "False") Boolean includeGRUsers) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** - * @deprecated + * @Deprecated */ - @GET - @Path("/users") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/users", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTFullUserList getUsers() throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** - * @deprecated + * @Deprecated */ - @GET - @Path("/groups") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "/groups", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTFullUserGroupList getUserGroups() throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; //==== /** - * @deprecated used for testing only + * @Deprecated used for testing only */ - @POST - @Path("/groups") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - void setUserGroups(@Multipart("groups")RESTFullUserGroupList groups) + @PostMapping( // + path = "/groups", // + consumes = { + MediaType.APPLICATION_XML_VALUE, + MediaType.TEXT_XML_VALUE, + MediaType.APPLICATION_JSON_VALUE} + ) + void setUserGroups(@RequestBody RESTFullUserGroupList groups) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** * only for debug/quick insert * takes as input the same xml returned by the related service GET operation * - * @deprecated used for testing only + * @Deprecated used for testing only */ - @POST - @Path("/users/short") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - void setUsers(@Multipart("users")RESTShortUserList users) + @PostMapping( // + path = "/users/short", // + consumes = { + MediaType.APPLICATION_XML_VALUE, + MediaType.TEXT_XML_VALUE, + MediaType.APPLICATION_JSON_VALUE} + ) + void setUsers(@RequestBody RESTShortUserList users) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** - * @deprecated used for testing only + * @Deprecated used for testing only */ - @POST - @Path("/instances/short") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - void setInstances(@Multipart("instances")RESTShortInstanceList instances) + @PostMapping( // + path = "/instances/short", // + consumes = { + MediaType.APPLICATION_XML_VALUE, + MediaType.TEXT_XML_VALUE, + MediaType.APPLICATION_JSON_VALUE} + ) + void setInstances(@RequestBody RESTShortInstanceList instances) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** - * @deprecated used for testing only + * @Deprecated used for testing only */ - @POST - @Path("/rules/short") - @Consumes({MediaType.APPLICATION_XML, MediaType.TEXT_XML}) - void setRules(@Multipart("rules")RESTOutputRuleList rules) + @PostMapping( // + path = "/rules/short", // + consumes = { + MediaType.APPLICATION_XML_VALUE, + MediaType.TEXT_XML_VALUE, + MediaType.APPLICATION_JSON_VALUE} + ) + void setRules(@RequestBody RESTOutputRuleList rules) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTGSInstanceService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTGSInstanceService.java index dc32fe02..29892a21 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTGSInstanceService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTGSInstanceService.java @@ -13,70 +13,82 @@ import org.geoserver.geofence.services.rest.model.RESTOutputInstance; import org.geoserver.geofence.services.rest.model.RESTShortInstanceList; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; - +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; + +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") +@RequestMapping(path = "/instances") public interface RESTGSInstanceService { /** * @return a sample user list * */ - @GET - @Path("/") - @Produces(MediaType.APPLICATION_XML) - RESTShortInstanceList getList(@QueryParam("nameLike") String nameLike, - @QueryParam("page") Integer page, - @QueryParam("entries") Integer entries) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @GET - @Path("/count/{nameLike}") - long count(@PathParam("nameLike") String nameLike); - - @GET - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - RESTOutputInstance get(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @GET - @Path("/name/{name") - @Produces(MediaType.APPLICATION_XML) - RESTOutputInstance get(@PathParam("name") String name) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @POST - @Path("/") - @Produces(MediaType.TEXT_PLAIN) - Response insert(@Multipart("instance") RESTInputInstance instance) throws BadRequestRestEx, ConflictRestEx, InternalErrorRestEx; - - @PUT - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - void update(@PathParam("id") Long id, - @Multipart("instance") RESTInputInstance instance) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @PUT - @Path("/name/{name}") - @Produces(MediaType.APPLICATION_XML) - void update(@PathParam("name") String name, - @Multipart("instance") RESTInputInstance instance) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + @GetMapping( // + path = "/", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTShortInstanceList getList(@RequestParam("nameLike") String nameLike, + @RequestParam("page") Integer page, + @RequestParam("entries") Integer entries) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @GetMapping( // + path = "/count/{nameLike}" + ) + long count(@PathVariable("nameLike") String nameLike); + + @GetMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTOutputInstance get(@PathVariable("id") Long id) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @GetMapping( // + path = "/name/{name}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTOutputInstance get(@PathVariable("name") String name) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @PostMapping( // + path = "/", // + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + ResponseEntity insert(@RequestBody RESTInputInstance instance) + throws BadRequestRestEx, ConflictRestEx, InternalErrorRestEx; + + @PutMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void update( + @PathVariable("id") Long id, + @RequestBody RESTInputInstance instance) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @PutMapping( // + path = "/name/{name}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void update( + @PathVariable("name") String name, + @RequestBody RESTInputInstance instance) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** * Deletes a GSInstance. @@ -89,11 +101,13 @@ void update(@PathParam("name") String name, * @throws ConflictRestEx (HTTP code 409) if any rule refers to the instance and cascade is false * @throws InternalErrorRestEx (HTTP code 500) */ - @DELETE - @Path("/id/{id}") - Response delete( - @PathParam("id") Long id, - @QueryParam("cascade") @DefaultValue("false") boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; + @DeleteMapping( // + path = "/id/{id}" + ) + ResponseEntity delete( + @PathVariable("id") Long id, + @RequestParam(name = "cascade", defaultValue = "false") boolean cascade) + throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; /** * Deletes a GSInstance. @@ -106,10 +120,12 @@ Response delete( * @throws ConflictRestEx (HTTP code 409) if any rule refers to the instance and cascade is false * @throws InternalErrorRestEx (HTTP code 500) */ - @DELETE - @Path("/name/{name}") - Response delete( - @PathParam("name") String name, - @QueryParam("cascade") @DefaultValue("false") boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; + @DeleteMapping( // + path = "/name/{name}" + ) + ResponseEntity delete( + @PathVariable("name") String name, + @RequestParam(name = "cascade", defaultValue = "false") boolean cascade) + throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTRuleService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTRuleService.java index 2b2a1b89..4a625037 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTRuleService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTRuleService.java @@ -2,9 +2,9 @@ * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ - package org.geoserver.geofence.services.rest; +import org.geoserver.geofence.services.exception.WebApplicationException.Response; import org.geoserver.geofence.services.rest.exception.BadRequestRestEx; import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; @@ -12,115 +12,112 @@ import org.geoserver.geofence.services.rest.model.RESTOutputRule; import org.geoserver.geofence.services.rest.model.RESTOutputRuleList; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") -public interface RESTRuleService -{ - @POST - @Path("/") - @Produces(MediaType.TEXT_PLAIN) - Response insert(@Multipart("rule") RESTInputRule rule) throws BadRequestRestEx, NotFoundRestEx; - - @GET - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - RESTOutputRule get(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx; - - @PUT - @Path("/id/{id}") - @Produces(MediaType.APPLICATION_XML) - void update(@PathParam("id") Long id, - @Multipart("rule") RESTInputRule rule) throws BadRequestRestEx, NotFoundRestEx; - - @DELETE - @Path("/id/{id}") - @Produces(MediaType.TEXT_XML) - Response delete(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx; - - @GET - @Path("/") - @Produces(MediaType.APPLICATION_XML) +@RequestMapping(path = "/rules") +public interface RESTRuleService { + + @PostMapping( // + path = "", // + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + ResponseEntity insert(@RequestBody RESTInputRule rule) + throws BadRequestRestEx, NotFoundRestEx; + + @GetMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTOutputRule get(@PathVariable("id") Long id) + throws BadRequestRestEx, NotFoundRestEx; + + @PutMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void update(@PathVariable("id") Long id, @RequestBody RESTInputRule rule) + throws BadRequestRestEx, NotFoundRestEx; + + @DeleteMapping( // + path = "/id/{id}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + ResponseEntity delete(@PathVariable("id") Long id) + throws BadRequestRestEx, NotFoundRestEx; + + @GetMapping( // + path = "", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTOutputRuleList get( - @QueryParam("page") Integer page, - @QueryParam("entries") Integer entries, - @QueryParam("full")@DefaultValue("false") boolean full, - - @QueryParam("userName") String userName, - @QueryParam("userAny") Boolean userAny, - - @QueryParam("groupName") String groupName, - @QueryParam("groupAny") Boolean groupAny, - - @QueryParam("instanceId") Long instanceId, - @QueryParam("instanceName") String instanceName, - @QueryParam("instanceAny") Boolean instanceAny, - - @QueryParam("service") String serviceName, - @QueryParam("serviceAny") Boolean serviceAny, - - @QueryParam("request") String requestName, - @QueryParam("requestAny") Boolean requestAny, - - @QueryParam("workspace") String workspace, - @QueryParam("workspaceAny") Boolean workspaceAny, - - @QueryParam("layer") String layer, - @QueryParam("layerAny") Boolean layerAny + @RequestParam(name = "page", required = false) Integer page, + @RequestParam(name = "entries", required = false) Integer entries, + @RequestParam(name = "full", defaultValue = "false") boolean full, + @RequestParam(name = "userName", required = false) String userName, + @RequestParam(name = "userAny", required = false) Boolean userAny, + @RequestParam(name = "groupName", required = false) String groupName, + @RequestParam(name = "groupAny", required = false) Boolean groupAny, + @RequestParam(name = "instanceId", required = false) Long instanceId, + @RequestParam(name = "instanceName", required = false) String instanceName, + @RequestParam(name = "instanceAny", required = false) Boolean instanceAny, + @RequestParam(name = "service", required = false) String serviceName, + @RequestParam(name = "serviceAny", required = false) Boolean serviceAny, + @RequestParam(name = "request", required = false) String requestName, + @RequestParam(name = "requestAny", required = false) Boolean requestAny, + @RequestParam(name = "workspace", required = false) String workspace, + @RequestParam(name = "workspaceAny", required = false) Boolean workspaceAny, + @RequestParam(name = "layer", required = false) String layer, + @RequestParam(name = "layerAny", required = false) Boolean layerAny ) throws BadRequestRestEx, InternalErrorRestEx; - @GET - @Path("/count") - long count( - @QueryParam("userName") String userName, - @QueryParam("userAny") Boolean userAny, - - @QueryParam("groupName") String groupName, - @QueryParam("groupAny") Boolean groupAny, - - @QueryParam("instanceId") Long instanceId, - @QueryParam("instanceName") String instanceName, - @QueryParam("instanceAny") Boolean instanceAny, - - @QueryParam("service") String serviceName, - @QueryParam("serviceAny") Boolean serviceAny, - - @QueryParam("request") String requestName, - @QueryParam("requestAny") Boolean requestAny, - - @QueryParam("workspace") String workspace, - @QueryParam("workspaceAny") Boolean workspaceAny, - - @QueryParam("layer") String layer, - @QueryParam("layerAny") Boolean layerAny + @GetMapping( // + path = "/count", + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + Long count( + @RequestParam(name = "userName", required = false) String userName, + @RequestParam(name = "userAny", required = false) Boolean userAny, + @RequestParam(name = "groupName", required = false) String groupName, + @RequestParam(name = "groupAny", required = false) Boolean groupAny, + @RequestParam(name = "instanceId", required = false) Long instanceId, + @RequestParam(name = "instanceName", required = false) String instanceName, + @RequestParam(name = "instanceAny", required = false) Boolean instanceAny, + @RequestParam(name = "service", required = false) String serviceName, + @RequestParam(name = "serviceAny", required = false) Boolean serviceAny, + @RequestParam(name = "request", required = false) String requestName, + @RequestParam(name = "requestAny", required = false) Boolean requestAny, + @RequestParam(name = "workspace", required = false) String workspace, + @RequestParam(name = "workspaceAny", required = false) Boolean workspaceAny, + @RequestParam(name = "layer", required = false) String layer, + @RequestParam(name = "layerAny", required = false) Boolean layerAny ); + /** - * Move the provided rules to the target priority. Rules will be sorted by their priority, first rule will be updated with a priority equal to the + * Move the provided rules to the target priority. Rules will be sorted by + * their priority, first rule will be updated with a priority equal to the * target priority and the next ones will get an incremented priority value. */ - @GET - @Path("/move") - @Produces(MediaType.TEXT_XML) - Response move( - @QueryParam("rulesIds") String rulesIds, - @QueryParam("targetPriority") Integer targetPriority + @GetMapping( // + path = "/move", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + ResponseEntity move( + @RequestParam("rulesIds") String rulesIds, + @RequestParam("targetPriority") Integer targetPriority ) throws BadRequestRestEx, InternalErrorRestEx; } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserGroupService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserGroupService.java index d7c213cb..8c70d368 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserGroupService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserGroupService.java @@ -2,10 +2,10 @@ * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ - package org.geoserver.geofence.services.rest; import org.geoserver.geofence.services.dto.ShortGroup; +import org.geoserver.geofence.services.exception.WebApplicationException.Response; import org.geoserver.geofence.services.rest.exception.BadRequestRestEx; import org.geoserver.geofence.services.rest.exception.ConflictRestEx; import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; @@ -13,104 +13,82 @@ import org.geoserver.geofence.services.rest.model.RESTInputGroup; import org.geoserver.geofence.services.rest.model.config.RESTFullUserGroupList; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; - -import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ - -@Path("/") -public interface RESTUserGroupService -{ - - /** - * @return a sample user list - * */ - @GET - @Path("/") - @Produces(MediaType.APPLICATION_XML) - RESTFullUserGroupList getList(@QueryParam("nameLike") String nameLike, - @QueryParam("page") Integer page, - @QueryParam("entries") Integer entries) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @GET - @Path("/count/{nameLike}") - long count(@PathParam("nameLike") String nameLike); - -// @GET -// @Path("/id/{id}") -// @Produces(MediaType.APPLICATION_XML) -// ShortGroup get(@PathParam("id") Long id) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @GET - @Path("/name/{name}") - @Produces(MediaType.APPLICATION_XML) - ShortGroup get(@PathParam("name") String name) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @POST - @Path("/") - @Produces(MediaType.TEXT_PLAIN) - Response insert(@Multipart("userGroup") RESTInputGroup group) throws BadRequestRestEx, ConflictRestEx, InternalErrorRestEx; - -// @PUT -// @Path("/id/{id}") -// @Produces(MediaType.APPLICATION_XML) -// void update(@PathParam("id") Long id, -// @Multipart("userGroup") RESTInputGroup group) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - @PUT - @Path("/name/{name}") - @Produces(MediaType.APPLICATION_XML) - void update(@PathParam("name") String name, - @Multipart("userGroup") RESTInputGroup group) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; - - /** - * Deletes a UserGroup. - * - * @param id The id of the group to delete - * @param cascade When true, also delete all the Rules referring to that group - * - * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal - * @throws NotFoundRestEx (HTTP code 404) if the group is not found - * @throws ConflictRestEx (HTTP code 409) if any rule refers to the group and cascade is false - * @throws InternalErrorRestEx (HTTP code 500) - */ -// @DELETE -// @Path("/id/{id}") -// Response delete( -// @PathParam("id") Long id, -// @QueryParam("cascade") @DefaultValue("false") boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; +@RequestMapping(path = "/groups") +public interface RESTUserGroupService { + + @GetMapping( // + path = "/", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTFullUserGroupList getList( + @RequestParam("nameLike") String nameLike, + @RequestParam("page") Integer page, + @RequestParam("entries") Integer entries) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @GetMapping( // + path = "/count/{nameLike}" + ) + long count(@PathVariable("nameLike") String nameLike); + + @GetMapping( // + path = "/name/{name}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + ShortGroup get(@PathVariable("name") String name) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; + + @PostMapping( // + path = "/", // + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + ResponseEntity insert(@RequestBody RESTInputGroup group) + throws BadRequestRestEx, ConflictRestEx, InternalErrorRestEx; + + @PutMapping( // + path = "/name/{name}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + void update( + @PathVariable("name") String name, + @RequestBody RESTInputGroup group) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; /** * Deletes a UserGroup. * * @param name The name of the group to delete - * @param cascade When true, also delete all the Rules referring to that group + * @param cascade When true, also delete all the Rules referring to that + * group * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal * @throws NotFoundRestEx (HTTP code 404) if the group is not found - * @throws ConflictRestEx (HTTP code 409) if any rule refers to the group and cascade is false + * @throws ConflictRestEx (HTTP code 409) if any rule refers to the group + * and cascade is false * @throws InternalErrorRestEx (HTTP code 500) */ - @DELETE - @Path("/name/{name}") - Response delete( - @PathParam("name") String name, - @QueryParam("cascade") @DefaultValue("false") boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; - + @DeleteMapping( // + path = "/name/{name}" + ) + ResponseEntity delete( + @PathVariable("name") String name, + @RequestParam(name = "cascade", defaultValue = "false") boolean cascade) + throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserService.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserService.java index 586abb54..fac5a148 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserService.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/RESTUserService.java @@ -2,9 +2,9 @@ * This code is licensed under the GPL 2.0 license, available at the root * application directory. */ - package org.geoserver.geofence.services.rest; +import org.geoserver.geofence.services.exception.WebApplicationException.Response; import org.geoserver.geofence.services.rest.exception.BadRequestRestEx; import org.geoserver.geofence.services.rest.exception.ConflictRestEx; import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; @@ -12,27 +12,25 @@ import org.geoserver.geofence.services.rest.model.RESTInputUser; import org.geoserver.geofence.services.rest.model.RESTOutputUser; import org.geoserver.geofence.services.rest.model.RESTShortUserList; -import org.geoserver.geofence.services.rest.model.util.IdName; +import org.springframework.http.HttpHeaders; -import javax.ws.rs.DELETE; -import javax.ws.rs.DefaultValue; -import javax.ws.rs.GET; -import javax.ws.rs.POST; -import javax.ws.rs.PUT; -import javax.ws.rs.Path; -import javax.ws.rs.PathParam; -import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.core.MediaType; -import javax.ws.rs.core.Response; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.DeleteMapping; -import org.apache.cxf.jaxrs.ext.multipart.Multipart; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; /** * * @author Emanuele Tajariol (etj at geo-solutions.it) */ -@Path("/") +@RequestMapping(path = "/users") public interface RESTUserService { /** @@ -41,19 +39,20 @@ public interface RESTUserService { * @param nameLike An optional LIKE filter on the username. * @param page In a paginated list, the page number, 0-based. If not null, * entries must be defined as well. - * @param entries In a paginated list, the number of entries per page. If not null, - * page must be defined as well. + * @param entries In a paginated list, the number of entries per page. If + * not null, page must be defined as well. * * @throws BadRequestRestEx (HTTP code 400) if page/entries do no match * @throws InternalErrorRestEx (HTTP code 500) */ - @GET - @Path("/") - @Produces(MediaType.APPLICATION_XML) + @GetMapping( // + path = "", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) RESTShortUserList getList( - @QueryParam("nameLike") String nameLike, - @QueryParam("page") Integer page, - @QueryParam("entries") Integer entries) + @RequestParam(name = "nameLike", required = false) String nameLike, + @RequestParam(name = "page", required = false) Integer page, + @RequestParam(name = "entries", required = false) Integer entries) throws BadRequestRestEx, InternalErrorRestEx; /** @@ -63,9 +62,11 @@ RESTShortUserList getList( * * @throws InternalErrorRestEx (HTTP code 500) */ - @GET - @Path("/count/{nameLike}") - long count(@PathParam("nameLike") String nameLike); + @GetMapping( // + path = "/count/{nameLike}", + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + Long count(@PathVariable("nameLike") String nameLike); /** * Returns a single user. @@ -75,10 +76,12 @@ RESTShortUserList getList( * @throws NotFoundRestEx (HTTP code 404) if no user with given name exists * @throws InternalErrorRestEx (HTTP code 500) */ - @GET - @Path("/name/{name}") - @Produces(MediaType.APPLICATION_XML) - RESTOutputUser get(@PathParam("name") String name) throws NotFoundRestEx, InternalErrorRestEx; + @GetMapping( // + path = "/name/{name}", // + produces = {MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE} + ) + RESTOutputUser get(@PathVariable("name") String name) + throws NotFoundRestEx, InternalErrorRestEx; /** * Inserts a new GSUser. @@ -91,10 +94,12 @@ RESTShortUserList getList( * @throws NotFoundRestEx (HTTP code 404) if the profile is not found * @throws InternalErrorRestEx (HTTP code 500) */ - @POST - @Path("/") - @Produces(MediaType.TEXT_PLAIN) - Response insert(@Multipart("user") RESTInputUser user) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx, ConflictRestEx; + @PostMapping( // + path = "/", // + produces = {MediaType.TEXT_PLAIN_VALUE} + ) + ResponseEntity insert(@RequestBody RESTInputUser user) + throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx, ConflictRestEx; /** * Updates a GSUser. @@ -103,13 +108,17 @@ RESTShortUserList getList( * @param user The new GSUser data as payload * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal - * @throws NotFoundRestEx (HTTP code 404) if the old user or the profile is not found + * @throws NotFoundRestEx (HTTP code 404) if the old user or the profile is + * not found * @throws InternalErrorRestEx (HTTP code 500) */ - @PUT - @Path("/id/{id}") - void update(@PathParam("id") Long id, - @Multipart("user") RESTInputUser user) throws BadRequestRestEx, NotFoundRestEx; + @PutMapping( // + path = "/id/{id}" + ) + void update( + @PathVariable("id") Long id, + @RequestBody RESTInputUser user) + throws BadRequestRestEx, NotFoundRestEx; /** * Updates a GSUser. @@ -118,35 +127,41 @@ void update(@PathParam("id") Long id, * @param user The new GSUser data as payload * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal - * @throws NotFoundRestEx (HTTP code 404) if the old user or the profile is not found + * @throws NotFoundRestEx (HTTP code 404) if the old user or the profile is + * not found * @throws InternalErrorRestEx (HTTP code 500) */ - @PUT - @Path("/name/{name}") - void update(@PathParam("name") String name, - @Multipart("user") RESTInputUser user) throws BadRequestRestEx, NotFoundRestEx; + @PutMapping( // + path = "/name/{name}"// + ) + void update( + @PathVariable("name") String name, + @RequestBody RESTInputUser user) + throws BadRequestRestEx, NotFoundRestEx; /** * Deletes a GSUser. * * @param name The name of the user to delete - * @param cascade When true, also delete all the Rules referring to that user + * @param cascade When true, also delete all the Rules referring to that + * user * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal * @throws NotFoundRestEx (HTTP code 404) if the user is not found * @throws if the user is used in a rule and cascade is false * @throws InternalErrorRestEx (HTTP code 500) */ - @DELETE - @Path("/name/{name}") - Response delete( - @PathParam("name") String name, - @QueryParam("cascade") @DefaultValue("false") boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; + @DeleteMapping( // + path = "/name/{name}" + ) + ResponseEntity delete( + @PathVariable("name") String name, + @RequestParam(name = "cascade", defaultValue = "false") boolean cascade) + throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx; //========================================================================= //=== Group association stuff //========================================================================= - /** * Adds a user into a userGroup * @@ -154,20 +169,21 @@ Response delete( * @param groupName The name of the group the user should be added into * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal - * @throws NotFoundRestEx (HTTP code 404) if the user or the group are not found + * @throws NotFoundRestEx (HTTP code 404) if the user or the group are not + * found * @throws InternalErrorRestEx (HTTP code 500) */ - @PUT - @Path("/name/{userName}/group/name/{groupName}") + @PutMapping( // + path = "/name/{userName}/group/name/{groupName}" + ) void addIntoGroup( - @PathParam("userName") String userName, - @PathParam("groupName") String groupName) + @PathVariable("userName") String userName, + @PathVariable("groupName") String groupName) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; //========================================================================= //=== Group removal stuff //========================================================================= - /** * Remove a user from a userGroup * @@ -175,13 +191,15 @@ void addIntoGroup( * @param groupName The name of the group the user should be removed from * * @throws BadRequestRestEx (HTTP code 400) if parameters are illegal - * @throws NotFoundRestEx (HTTP code 404) if the user or the group are not found + * @throws NotFoundRestEx (HTTP code 404) if the user or the group are not + * found * @throws InternalErrorRestEx (HTTP code 500) */ - @DELETE - @Path("/name/{userName}/group/name/{groupName}") + @DeleteMapping( // + path = "/name/{userName}/group/name/{groupName}" + ) void removeFromGroup( - @PathParam("userName") String userName, - @PathParam("groupName") String groupName) + @PathVariable("userName") String userName, + @PathVariable("groupName") String groupName) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx; } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/BadRequestRestEx.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/BadRequestRestEx.java index bf5e9e87..771e5c65 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/BadRequestRestEx.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/BadRequestRestEx.java @@ -5,8 +5,7 @@ package org.geoserver.geofence.services.rest.exception; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +import org.springframework.http.HttpStatus; /** * @@ -20,6 +19,6 @@ public class BadRequestRestEx extends GeoFenceRestEx { private static final long serialVersionUID = -2585698525010604674L; public BadRequestRestEx(String message) { - super(message, Response.status(Status.BAD_REQUEST).type("text/plain").entity(message).build()); + super(HttpStatus.BAD_REQUEST, message); } } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/ConflictRestEx.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/ConflictRestEx.java index df89ea31..eb5aca31 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/ConflictRestEx.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/ConflictRestEx.java @@ -5,8 +5,7 @@ package org.geoserver.geofence.services.rest.exception; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +import org.springframework.http.HttpStatus; /** * @@ -15,6 +14,6 @@ public class ConflictRestEx extends GeoFenceRestEx { public ConflictRestEx(String message) { - super(message, Response.status(Status.CONFLICT).type("text/plain").entity(message).build()); + super(HttpStatus.CONFLICT, message); } } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/GeoFenceRestEx.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/GeoFenceRestEx.java index 3c36bf1c..f1de19ef 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/GeoFenceRestEx.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/GeoFenceRestEx.java @@ -5,25 +5,17 @@ package org.geoserver.geofence.services.rest.exception; -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.Response; +import org.springframework.http.HttpStatus; +import org.springframework.web.server.ResponseStatusException; /** * Used as a catchall when forwarding exceptions * * @author ETj (etj at geo-solutions.it) */ -public abstract class GeoFenceRestEx extends WebApplicationException { +public abstract class GeoFenceRestEx extends ResponseStatusException { - private String message; - - public GeoFenceRestEx(String message, Response response) { - super(response); - this.message = message; - } - - @Override - public String getMessage() { - return message; + protected GeoFenceRestEx(HttpStatus status, String reason) { + super(status, reason); } } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/InternalErrorRestEx.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/InternalErrorRestEx.java index b2f8db40..6c87453c 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/InternalErrorRestEx.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/InternalErrorRestEx.java @@ -5,8 +5,7 @@ package org.geoserver.geofence.services.rest.exception; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +import org.springframework.http.HttpStatus; /** * @@ -20,6 +19,6 @@ public class InternalErrorRestEx extends GeoFenceRestEx { private static final long serialVersionUID = 9014519381293787498L; public InternalErrorRestEx(String message) { - super(message, Response.status(Status.INTERNAL_SERVER_ERROR).type("text/plain").entity(message).build()); + super(HttpStatus.INTERNAL_SERVER_ERROR, message); } } diff --git a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/NotFoundRestEx.java b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/NotFoundRestEx.java index 7231307c..7b3ea56e 100644 --- a/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/NotFoundRestEx.java +++ b/src/extension/rest/api/src/main/java/org/geoserver/geofence/services/rest/exception/NotFoundRestEx.java @@ -5,8 +5,7 @@ package org.geoserver.geofence.services.rest.exception; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; +import org.springframework.http.HttpStatus; /** * @@ -20,6 +19,6 @@ public class NotFoundRestEx extends GeoFenceRestEx { private static final long serialVersionUID = 1263563388095079971L; public NotFoundRestEx(String message) { - super(message, Response.status(Status.NOT_FOUND).type("text/plain").entity(message).build()); + super(HttpStatus.NOT_FOUND, message); } } diff --git a/src/extension/rest/client/pom.xml b/src/extension/rest/client/pom.xml index e8bd7a6b..de8c7d2a 100644 --- a/src/extension/rest/client/pom.xml +++ b/src/extension/rest/client/pom.xml @@ -42,11 +42,47 @@ - + + + + + org.glassfish.jersey.core + jersey-client + 2.29.1 + + + org.glassfish.jersey.media + jersey-media-json-jackson + 2.29.1 + + + + + org.glassfish.jersey.inject + jersey-hk2 + 2.29.1 + + org.glassfish.jersey.media + jersey-media-moxy + 2.29.1 + + + org.glassfish.jersey.media + jersey-media-jaxb + 2.29.1 + + + + @@ -60,12 +96,12 @@ log4j log4j - + diff --git a/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/DynamicInvocationHandler.java b/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/DynamicInvocationHandler.java new file mode 100644 index 00000000..8c0a9d03 --- /dev/null +++ b/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/DynamicInvocationHandler.java @@ -0,0 +1,227 @@ +/* + + */ +package org.geoserver.geofence.services.rest; + + +import java.awt.print.Book; +import java.lang.annotation.Annotation; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import javax.naming.OperationNotSupportedException; + +import javax.ws.rs.client.Client; +import javax.ws.rs.client.ClientBuilder; +import javax.ws.rs.client.Invocation.Builder; +import javax.ws.rs.client.WebTarget; +import javax.ws.rs.core.Response; + + +import org.apache.log4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; + + + +public class DynamicInvocationHandler implements InvocationHandler { + + private static Logger LOGGER = Logger.getLogger(DynamicInvocationHandler.class); + + private final Class restService; + private final String baseUrl; + + + private String classPathPrefix = null; + + public DynamicInvocationHandler(Class restService, String baseUrl) { + this.restService = restService; + this.baseUrl = baseUrl; + + // gather class-level RequestHandler + RequestMapping rm = (RequestMapping)restService.getAnnotation(RequestMapping.class); + if(rm != null) { + classPathPrefix = rm.path()[0]; + } + + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) + throws Throwable { + + LOGGER.debug("Invoked method: "+ method.getName()); + + + CoalescedReqMap rm = getRequestMapping(method); + if(rm == null) { + throw new RuntimeException("RequestMapping not found for method " + method.getName()); + } + + LOGGER.debug(" ===> RequestMapping found:: "+ rm); + + + String[] methodPaths = rm.path; +// if(methodPaths != null) { +// for (String methodPath : methodPaths) { +// } +// } + + Client client = ClientBuilder.newClient(); + WebTarget target = client.target(baseUrl); + LOGGER.debug(" BASE target: "+ target); + + if(classPathPrefix != null) + target = target.path(classPathPrefix); + + LOGGER.debug(" CLASS target: "+ target); + + if(methodPaths != null) { + if(methodPaths.length > 1) { + throw new IllegalStateException("Unexpected mathod path len"); + } + + String methodPath = methodPaths[0]; + LOGGER.debug(" Method path: "+ methodPath); + + if(methodPath.contains("{")) { + methodPath = bindArgs(method, methodPath, args); + LOGGER.info(" Bound Method path: "+ methodPath); + } + + target = target.path(methodPath); + } + + LOGGER.info(" METHOD target: "+ target); + + + + Builder request = target.request(rm.produces); + Response response; + switch(rm.method[0]) { + case GET: + response = request.get(); + break; + case DELETE: + response = request.delete(); + break; + default: + throw new OperationNotSupportedException("Method " + rm.method[0] + " not supported yet"); + } + + LOGGER.info("Request " + rm.method[0] + " " + target.getUri()); + LOGGER.info("Accept: " + Arrays.deepToString(rm.produces)); + LOGGER.info("Response: " + response.getStatus() + " " + response.getStatusInfo()); + LOGGER.info("Expected type: " + method.getReturnType()); + + if(response.getStatus() > 399) { + throw new IllegalArgumentException("request status: " + response.getStatus() + " " + response.getStatusInfo()); + } + + Class responseType = method.getReturnType(); + if(responseType == ResponseEntity.class) { + return response.getEntity(); + + } else { + return response.readEntity(responseType); + } + +// System.out.println("Response code: " + response.getStatus()); +// Book book = response.readEntity(Book.class); +// System.out.println("Title: " + book.getTitle()); +// +// +// return 42; + } + + + private CoalescedReqMap getRequestMapping(Method method) throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException { + + for (Annotation annotation : method.getAnnotations()) { + CoalescedReqMap rm = getSuperAnnotations(method, annotation); + if(rm != null) { + return rm; + } + } + + return null; + + } + + private CoalescedReqMap getSuperAnnotations(Method method, Annotation annotation) { + +// LOGGER.info(" Check Annotation for method " + method.getName() + " -> " + annotation.annotationType().getSimpleName() + " TYPE " + annotation ); + + if(annotation instanceof RequestMapping) { + RequestMapping rm = (RequestMapping) annotation; + CoalescedReqMap ret = new CoalescedReqMap(); + ret.method = rm.method(); + ret.path = rm.path(); + ret.produces = rm.produces(); + return ret; + } + + for (Annotation superann : annotation.annotationType().getAnnotations()) { +// LOGGER.info(" Checking superannotation -> " + superann.annotationType().getSimpleName()); + if(superann.annotationType() == RequestMapping.class) { + CoalescedReqMap ret = new CoalescedReqMap(); + ret.method = ((RequestMapping) superann).method(); + //ret.path = ((RequestMapping) annotation).path(); + +// for (Method m : annotation.annotationType().getMethods()) { +// LOGGER.info(" Found method " + annotation.annotationType().getSimpleName() + " :: " + m ); +// } + + try { + ret.path = (String[])annotation.annotationType().getMethod("path").invoke(annotation); + ret.produces = (String[])annotation.annotationType().getMethod("produces").invoke(annotation); + } catch (Exception ex) { + LOGGER.warn("Introspection error", ex); + return null; + } + return ret; + } + } + + return null; + } + + private String bindArgs(Method method, String path, Object[] args) { + for (int i = 0; i < method.getParameterCount(); i++) { + Annotation[] pAnnArr = method.getParameterAnnotations()[i]; + for (Annotation pAnn : pAnnArr) { + LOGGER.debug(" - Arg annotation: " + pAnn); + if(pAnn.annotationType() == PathVariable.class) { + PathVariable pv = (PathVariable)pAnn; + String varName = pv.value(); + String value = args[i] == null ? "" : args[i].toString(); + LOGGER.debug(" - Binding var " + varName + " = " + value); + + path = path.replace("{"+varName+"}", value); + } + } + } + + return path; + } + + static class CoalescedReqMap { + public String[] path = null; + public RequestMethod[] method = null; + public String[] produces = null; + + + @Override + public String toString() { + String p = path != null? path.length + "/"+path[0]: "-"; + String m = method != null? method.length + "/"+ method[0].name() : "-"; + + return "CoalescedReqMap{" + "path=" + p + ", method=" + m + '}'; + } + } + +} \ No newline at end of file diff --git a/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/GeoFenceClient.java b/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/GeoFenceClient.java index 53300820..0d34ee05 100644 --- a/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/GeoFenceClient.java +++ b/src/extension/rest/client/src/main/java/org/geoserver/geofence/services/rest/GeoFenceClient.java @@ -5,16 +5,9 @@ package org.geoserver.geofence.services.rest; -import org.geoserver.geofence.services.rest.RESTBatchService; -import org.geoserver.geofence.services.rest.RESTUserGroupService; -import org.geoserver.geofence.services.rest.RESTUserService; -import org.geoserver.geofence.services.rest.RESTGSInstanceService; -import org.geoserver.geofence.services.rest.RESTRuleService; +import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.Map; -import org.apache.cxf.common.util.Base64Utility; -import org.apache.cxf.jaxrs.client.JAXRSClientFactory; -import org.apache.cxf.jaxrs.client.WebClient; /** * @@ -37,23 +30,27 @@ public GeoFenceClient() { // since it's specified in the applicationcontext, it can not be automatically retrieved by the proxy client protected T getService(Class clazz, String endpoint) { + + T proxy = (T)Proxy.newProxyInstance(this.getClass().getClassLoader(), + new Class[] { clazz }, + new DynamicInvocationHandler(clazz, restUrl)); + if(services.containsKey(clazz)) return (T)services.get(clazz); if(restUrl == null) new IllegalStateException("GeoFence URL not set"); - synchronized(services) { -// T proxy = JAXRSClientFactory.create(restUrl, clazz, username, password, null); +// synchronized(services) { +// T proxy = JAXRSClientFactory.create(restUrl+"/"+endpoint, clazz); +// String authorizationHeader = "Basic " + Base64Utility.encode((username+":"+password).getBytes()); +// WebClient.client(proxy).header("Authorization", authorizationHeader); - T proxy = JAXRSClientFactory.create(restUrl+"/"+endpoint, clazz); - String authorizationHeader = "Basic " + Base64Utility.encode((username+":"+password).getBytes()); - WebClient.client(proxy).header("Authorization", authorizationHeader); // WebClient.client(proxy).accept("text/xml"); services.put(clazz, proxy); return proxy; - } +// } } //========================================================================== @@ -100,7 +97,7 @@ public String getRestUrl() { return restUrl; } - public void setGeostoreRestUrl(String restUrl) { + public void setBaseRestUrl(String restUrl) { this.restUrl = restUrl; } diff --git a/src/extension/rest/client/src/test/java/org/geoserver/geofence/services/rest/GeoFenceClientTest.java b/src/extension/rest/client/src/test/java/org/geoserver/geofence/services/rest/GeoFenceClientTest.java index bbe9c193..7f933160 100644 --- a/src/extension/rest/client/src/test/java/org/geoserver/geofence/services/rest/GeoFenceClientTest.java +++ b/src/extension/rest/client/src/test/java/org/geoserver/geofence/services/rest/GeoFenceClientTest.java @@ -21,8 +21,7 @@ import java.net.ConnectException; import java.util.Arrays; -import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; +import java.util.List; import org.apache.log4j.Logger; import org.junit.AfterClass; @@ -31,13 +30,15 @@ import org.junit.Test; import static org.junit.Assume.*; import static org.junit.Assert.*; +import org.springframework.http.HttpHeaders; +import org.springframework.http.ResponseEntity; /** * * @author ETj (etj at geo-solutions.it) */ public class GeoFenceClientTest { - private final static Logger LOGGER = LogManager.getLogger(GeoFenceClientTest.class); + private final static Logger LOGGER = Logger.getLogger(GeoFenceClientTest.class); public GeoFenceClientTest() { } @@ -62,7 +63,7 @@ public void before() throws Exception { protected GeoFenceClient createClient() { GeoFenceClient client = new GeoFenceClient(); - client.setGeostoreRestUrl("http://localhost:9191/geofence/rest"); + client.setBaseRestUrl("http://localhost:9191/geofence/rest"); client.setUsername("admin"); client.setPassword("admin"); @@ -72,10 +73,10 @@ protected GeoFenceClient createClient() { protected void removeAll() { LOGGER.info("Removing GeoFence resources..."); GeoFenceClient client = createClient(); + removeRules(client); removeUsers(client); removeGroups(client); removeInstances(client); - removeRules(client); LOGGER.info("Finished removing GeoFence resources..."); } @@ -203,7 +204,7 @@ public void testReassign() { } { - assertEquals(1, client.getUserService().count("%")); + assertEquals(1, (long)client.getUserService().count("%")); assertEquals(1, client.getUserService().get("pippo").getGroups().size()); } @@ -252,9 +253,11 @@ public void testBaseRule() { inputRule.setGrant(GrantType.ALLOW); inputRule.setPosition(new RESTRulePosition(RESTRulePosition.RulePosition.offsetFromTop, 0)); - Response response = client.getRuleService().insert(inputRule); - assertNotNull(response.getEntityTag()); - String id = response.getEntityTag().getValue(); + ResponseEntity response = client.getRuleService().insert(inputRule); + List etag = response.getHeaders().get(HttpHeaders.ETAG); + assertNotNull(etag); + assertFalse(etag.isEmpty()); + String id = etag.get(0); assertNotNull(id); RESTOutputRule outRule = client.getRuleService().get(Long.parseLong(id)); diff --git a/src/extension/rest/impl/pom.xml b/src/extension/rest/impl/pom.xml index 84fba5c0..894303d9 100644 --- a/src/extension/rest/impl/pom.xml +++ b/src/extension/rest/impl/pom.xml @@ -37,6 +37,11 @@ org.geoserver.geofence geofence-services-api + + + org.geoserver.geofence + geofence-services-impl + org.geoserver.geofence @@ -50,41 +55,27 @@ - - com.sun.xml.ws - jaxws-ri - - pom - - - - - org.apache.cxf - cxf-rt-frontend-jaxrs - - - - - - org.apache.cxf - cxf-rt-rs-extension-providers - - - - org.codehaus.jackson - jackson-jaxrs - 1.9.13 - + + + + + - javax.annotation - jsr250-api - 1.0 + com.fasterxml.jackson.core + jackson-databind + 2.10.1 - - javassist javassist @@ -101,22 +92,22 @@ - net.sf.json-lib - json-lib - 2.4 - jdk15 - compile + org.springframework + spring-web - xom - xom - 1.1 + org.springframework + spring-webmvc + + + org.springframework + spring-context + + + org.springframework + spring-test + test - - org.geoserver.geofence @@ -124,6 +115,12 @@ test + + org.slf4j + slf4j-log4j12 + 1.7.30 + test + log4j log4j @@ -134,11 +131,20 @@ junit test - - + + + + + + javax.servlet + javax.servlet-api + 3.1.0 + provided @@ -154,12 +160,6 @@ test - - org.springframework - spring-context - test - - diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthUser.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthUser.java deleted file mode 100644 index 27c317b6..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthUser.java +++ /dev/null @@ -1,56 +0,0 @@ -/* (c) 2014 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.auth; - -/** - * - * @author ETj (etj at geo-solutions.it) - */ -public class AuthUser -{ - - private String name; - - public String getName() - { - return name; - } - - public void setName(String name) - { - this.name = name; - } - - @Override - public boolean equals(Object obj) - { - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - - final AuthUser other = (AuthUser) obj; - if ((this.name == null) ? (other.name != null) : (!this.name.equals(other.name))) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int hash = 5; - hash = (19 * hash) + ((this.name != null) ? this.name.hashCode() : 0); - - return hash; - } -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthenticationHandler.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthenticationHandler.java deleted file mode 100644 index ee36c351..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthenticationHandler.java +++ /dev/null @@ -1,193 +0,0 @@ -/* (c) 2014 - 2017 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.auth; - -import java.io.IOException; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.util.Arrays; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.configuration.security.AuthorizationPolicy; -import org.apache.cxf.endpoint.Endpoint; -import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor; -import org.apache.cxf.interceptor.Fault; -import org.apache.cxf.message.Exchange; -import org.apache.cxf.message.Message; -import org.apache.cxf.phase.Phase; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger;; - - - -/** - * Adds basic authentication to CXF services by using login operation. - * - * @author Tobia di Pisa (tobia.dipisa at geo-solutions.it) - * - * @see http://chrisdail.com/2008/08/13/http-basic-authentication-with-apache-cxf-revisited/ - * - */ -public class AuthenticationHandler extends AbstractInDatabindingInterceptor -{ - - private static final Logger LOGGER = LogManager.getLogger(AuthenticationHandler.class); - - private String realm; - - public AuthenticationHandler() - { - super(Phase.UNMARSHAL); - } - - /** - * @param realm the realm to set - */ - public void setRealm(String realm) - { - this.realm = realm; - } - - /** - * @param username - * @param password - * @return boolean - */ - private boolean isAuthenticated(String username, String password) - { - LOGGER.warn("FORCING AUTH"); - - return true; - } - - /* (non-Javadoc) - * @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message) - */ - @Override - public void handleMessage(Message message) throws Fault - { - AuthorizationPolicy policy = (AuthorizationPolicy) message.get(AuthorizationPolicy.class); - - // - // TODO: To manage the public access (guest). - // - if (policy == null) - { - sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED); - - return; - } - - String username = policy.getUserName(); - String password = policy.getPassword(); - - if (isAuthenticated(username, password)) - { - // //////////////////////////////////////// - // let request to continue - // //////////////////////////////////////// - return; - } - else - { - // ///////////////////////////////////////////////////////////////////// - // authentication failed, request the authetication, - // add the realm name if needed to the value of WWW-Authenticate - // ///////////////////////////////////////////////////////////////////// - sendErrorResponse(message, HttpURLConnection.HTTP_UNAUTHORIZED); - - return; - } - } - - /** - * @param message - * @param responseCode - */ - @SuppressWarnings("unchecked") - private void sendErrorResponse(Message message, int responseCode) - { - - Message outMessage = getOutMessage(message); - outMessage.put(Message.RESPONSE_CODE, responseCode); - - // //////////////////////////////////////// - // Set the response headers - // //////////////////////////////////////// - Map> responseHeaders = (Map>) message.get(Message.PROTOCOL_HEADERS); - - if (responseHeaders != null) - { - responseHeaders.put("WWW-Authenticate", Arrays.asList("Basic realm=\"" + realm + "\"")); - responseHeaders.put("Content-Length", Arrays.asList("0")); - } - - message.getInterceptorChain().abort(); - try - { - message.getExchange().getConduit(message).prepare(outMessage); // TEST ME -// getConduit(message).prepare(outMessage); - - OutputStream os = outMessage.getContent(OutputStream.class); - String errmsg = "Error " + responseCode + ": "; - os.write(errmsg.getBytes()); - LOGGER.info("Sending error " + responseCode); - - close(outMessage); - } - catch (IOException e) - { - LOGGER.warn(e.getMessage(), e); - } - } - - /** - * @param inMessage - * @return Message - */ - private Message getOutMessage(Message inMessage) - { - Exchange exchange = inMessage.getExchange(); - Message outMessage = exchange.getOutMessage(); - if (outMessage == null) - { - Endpoint endpoint = exchange.get(Endpoint.class); - outMessage = endpoint.getBinding().createMessage(); - exchange.setOutMessage(outMessage); - } - outMessage.putAll(inMessage); - - return outMessage; - } - - /** - * @param inMessage - * @return Conduit - * @throws IOException - */ -// private Conduit getConduit(Message inMessage) throws IOException -// { -// Exchange exchange = inMessage.getExchange(); -// EndpointReferenceType target = exchange.get(EndpointReferenceType.class); -// Conduit conduit = exchange.getDestination().getBackChannel(inMessage, null, target); -// exchange.setConduit(conduit); -// -// return conduit; -// } - - /** - * @param outMessage - * @throws IOException - */ - private void close(Message outMessage) throws IOException - { - OutputStream os = outMessage.getContent(OutputStream.class); - os.flush(); - os.close(); - } - -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthorizationHandler.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthorizationHandler.java deleted file mode 100644 index d736bb2d..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/AuthorizationHandler.java +++ /dev/null @@ -1,197 +0,0 @@ -/* (c) 2014 - 2017 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.auth; - -import java.lang.reflect.Method; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.cxf.interceptor.Fault; -import org.apache.cxf.interceptor.security.AccessDeniedException; -import org.apache.cxf.message.Message; -import org.apache.cxf.phase.AbstractPhaseInterceptor; -import org.apache.cxf.phase.Phase; -import org.apache.cxf.security.SecurityContext; -import org.apache.cxf.service.Service; -import org.apache.cxf.service.invoker.MethodDispatcher; -import org.apache.cxf.service.model.BindingOperationInfo; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - - -public class AuthorizationHandler extends AbstractPhaseInterceptor -{ - - private static final Logger LOGGER = LogManager.getLogger(AuthorizationHandler.class); -// private static final String ALL_ROLES = "*"; - - private static Map> parseRolesMap(Map rolesMap) - { - Map> map = new HashMap>(); - for (Map.Entry entry : rolesMap.entrySet()) - { - map.put(entry.getKey(), Arrays.asList(entry.getValue().split(" "))); - } - - return map; - } - - private Map> methodRolesMap = new HashMap>(); - private Map> userRolesMap = Collections.emptyMap(); - private List globalRoles = Collections.emptyList(); - - public AuthorizationHandler() - { - super(Phase.PRE_INVOKE); - } - - public void handleMessage(Message message) throws Fault - { - SecurityContext sc = message.get(SecurityContext.class); - if (sc == null) - { - return; - } - - Method method = getTargetMethod(message); - - if (authorize(sc, method)) - { - return; - } - - throw new AccessDeniedException("Unauthorized"); - } - - protected Method getTargetMethod(Message m) - { - BindingOperationInfo bop = m.getExchange().get(BindingOperationInfo.class); - if (bop != null) - { - MethodDispatcher md = (MethodDispatcher) m.getExchange().get(Service.class).get(MethodDispatcher.class.getName()); - - return md.getMethod(bop); - } - - Method method = (Method) m.get("org.apache.cxf.resource.method"); - if (method != null) - { - return method; - } - throw new AccessDeniedException("Method is not available : Unauthorized"); - } - - protected boolean authorize(SecurityContext sc, Method method) - { - List expectedRoles = getExpectedRoles(method); - if (expectedRoles.isEmpty()) - { - - List denyRoles = getDenyRoles(method); - - return denyRoles.isEmpty() ? true : isUserInRole(sc, denyRoles, true); - } - - if (isUserInRole(sc, expectedRoles, false)) - { - return true; - } - if (sc.getUserPrincipal() != null) - { - LOGGER.error(sc.getUserPrincipal().getName() + " is not authorized"); - } - - return false; - } - -// protected boolean isUserAllRole(SecurityContext sc, List roles, boolean deny) { -// -// if (roles.size() == 1 && ALL_ROLES.equals(roles.get(0))) { -// return !deny; -// } -// -// for (String role : roles) { -// if (sc.isUserInRole(role)) { -// return !deny; -// } -// } -// return deny; -// } - - protected boolean isUserInRole(SecurityContext sc, List roles, boolean deny) - { -// System.out.println(":::::::::::::::::::::::: 0"); -// if (!isUserAllRole(sc, roles, deny)) { -// System.out.println(":::::::::::::::::::::::: 1"); -// return false; -// } - - // Additional check. - if (!userRolesMap.isEmpty()) - { - List userRoles = userRolesMap.get(sc.getUserPrincipal().getName()); - if (userRoles == null) - { - return false; - } - for (String role : roles) - { - if (userRoles.contains(role)) - { - return true; - } - } - - return false; - } - else - { - return true; - } - } - - protected List getExpectedRoles(Method method) - { - List roles = methodRolesMap.get(method.getName()); - if (roles != null) - { - return roles; - } - - return globalRoles; - } - - - public void setMethodRolesMap(Map rolesMap) - { - methodRolesMap.putAll(parseRolesMap(rolesMap)); - } - - public void setUserRolesMap(Map rolesMap) - { - userRolesMap = parseRolesMap(rolesMap); - } - - public void setGlobalRoles(String roles) - { - globalRoles = Arrays.asList(roles.split(" ")); - } - - /** - * Returns a list of roles to be denied for a given method. - * @param method Method - * @return list, empty if no roles are available - */ - protected List getDenyRoles(Method method) - { - return Collections.emptyList(); - } - -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceAuthenticationInterceptor.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceAuthenticationInterceptor.java deleted file mode 100644 index d4b8849b..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceAuthenticationInterceptor.java +++ /dev/null @@ -1,73 +0,0 @@ -/* (c) 2014 - 2017 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.auth; - - -import org.apache.cxf.configuration.security.AuthorizationPolicy; -import org.apache.cxf.interceptor.Fault; -import org.apache.cxf.message.Message; -import org.apache.cxf.phase.AbstractPhaseInterceptor; -import org.apache.cxf.phase.Phase; -import org.apache.cxf.security.SecurityContext; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - -/** - * - * Starting point was JAASLoginInterceptor - * - * @author ETj (etj at geo-solutions.it) - */ -public class GeofenceAuthenticationInterceptor extends AbstractPhaseInterceptor -{ - - private static final Logger LOGGER = LogManager.getLogger(GeofenceAuthenticationInterceptor.class); - - // TODO: inject user service - - public GeofenceAuthenticationInterceptor() - { - super(Phase.UNMARSHAL); - } - - @Override - public void handleMessage(Message message) throws Fault - { - - LOGGER.info("In handleMessage"); - LOGGER.info("Message --> " + message); - - String name = null; - String password = null; - - AuthUser user = null; - - AuthorizationPolicy policy = (AuthorizationPolicy) message.get(AuthorizationPolicy.class); - if (policy != null) - { - name = policy.getUserName(); - password = policy.getPassword(); - - LOGGER.info("Requesting user: " + name); - // TODO: read user from DB - // if user and pw do not match, throw new AuthenticationException("Unauthorized"); - - user = new AuthUser(); - user.setName(name); - - } - else - { - LOGGER.info("No requesting user -- GUEST access"); - } - - GeofenceSecurityContext securityContext = new GeofenceSecurityContext(); - GeofencePrincipal principal = (user != null) ? new GeofencePrincipal(user) : GeofencePrincipal.createGuest(); - securityContext.setPrincipal(principal); - - message.put(SecurityContext.class, securityContext); - } -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofencePrincipal.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofencePrincipal.java deleted file mode 100644 index 57fcdd12..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofencePrincipal.java +++ /dev/null @@ -1,75 +0,0 @@ -/* (c) 2014 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.auth; - -import java.security.Principal; - - -/** - * - * @author ETj (etj at geo-solutions.it) - */ -public class GeofencePrincipal implements Principal -{ - - static GeofencePrincipal createGuest() - { - return new GeofencePrincipal(); - } - - private AuthUser user; - - public GeofencePrincipal() - { - } - - public GeofencePrincipal(AuthUser user) - { - if (user == null) - { - throw new NullPointerException("Null user"); - } - this.user = user; - } - - @Override - public String getName() - { - return (user != null) ? user.getName() : "GUEST"; - } - - @Override - public boolean equals(Object obj) - { - if (obj == null) - { - return false; - } - if (getClass() != obj.getClass()) - { - return false; - } - - final GeofencePrincipal other = (GeofencePrincipal) obj; - if ((this.user != other.user) && ((this.user == null) || !this.user.equals(other.user))) - { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - int hash = 3; - hash = (97 * hash) + ((this.user != null) ? this.user.hashCode() : 0); - - return hash; - } - - -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceSecurityContext.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceSecurityContext.java deleted file mode 100644 index df6f726c..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/GeofenceSecurityContext.java +++ /dev/null @@ -1,73 +0,0 @@ -/* (c) 2014 - 2017 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.auth; - -import java.security.Principal; - -import org.apache.cxf.security.SecurityContext; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - -/** - * - * @author ETj (etj at geo-solutions.it) - */ -public class GeofenceSecurityContext implements SecurityContext -{ - - private static final Logger LOGGER = LogManager.getLogger(GeofenceSecurityContext.class); - - private GeofencePrincipal principal; - - public void setPrincipal(GeofencePrincipal principal) - { - this.principal = principal; - } - - @Override - public Principal getUserPrincipal() - { - return principal; - } - - - @Override - public boolean isUserInRole(String role) - { - boolean ret = isUserInRoleAux(role); - LOGGER.info("User" + principal.getName() + " in " + role + " : " + ret); - - return ret; - } - - public boolean isUserInRoleAux(String role) - { - // TODO pls use an enum here - if ("*".equals(role)) - { - return true; - } - - if ("guest".equalsIgnoreCase(role)) - { - return true; - } - - if ("user".equalsIgnoreCase(role)) // so user is registered - { - return true; - } - - if ("admin".equalsIgnoreCase(principal.getName()) && "admin".equalsIgnoreCase(role)) - { - return true; - } - - return false; - } - - -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/JAXBContextResolver.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/JAXBContextResolver.java deleted file mode 100644 index 42141af2..00000000 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/auth/JAXBContextResolver.java +++ /dev/null @@ -1,51 +0,0 @@ -/* (c) 2014 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.auth; - - -import javax.ws.rs.ext.ContextResolver; -import javax.ws.rs.ext.Provider; -import javax.xml.bind.JAXBContext; - - -/** - * Class JAXBContextResolver. - * - * @author ETj (etj at geo-solutions.it) - */ -@Provider -public class JAXBContextResolver implements ContextResolver -{ - - private static final JAXBContext context = initContext(); - - private static JAXBContext initContext() - { - JAXBContext context = null; - -// try { -// context = null; -// JAXBContext.newInstance(SearchFilter.class, AndFilter.class, -// AttributeFilter.class, FieldFilter.class, NotFilter.class, OrFilter.class); -// } catch (JAXBException e) { -// throw new RuntimeException(e); -// } - - return context; - } - - /* (non-Javadoc) - * @see javax.ws.rs.ext.ContextResolver#getContext(java.lang.Class) - */ - @Override - public JAXBContext getContext(Class clazz) - { -// if(clazz.equals(SearchFilter.class)) -// return context; - return null; - } - -} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/BaseRESTServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/BaseRESTServiceImpl.java index 5bca9b53..eb44bd4e 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/BaseRESTServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/BaseRESTServiceImpl.java @@ -24,7 +24,8 @@ import org.geoserver.geofence.services.rest.model.util.IdName; import org.apache.log4j.LogManager; -import org.apache.log4j.Logger;; +import org.apache.log4j.Logger;import org.springframework.beans.factory.annotation.Autowired; +; /** * @@ -34,10 +35,15 @@ public abstract class BaseRESTServiceImpl { private static final Logger LOGGER = LogManager.getLogger(BaseRESTServiceImpl.class); - protected UserAdminService userAdminService; + @Autowired + protected UserAdminService userAdminService; + @Autowired protected UserGroupAdminService userGroupAdminService; + @Autowired protected InstanceAdminService instanceAdminService; + @Autowired protected RuleAdminService ruleAdminService; + @Autowired protected AdminRuleAdminService adminRuleAdminService; diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTAdminRuleServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTAdminRuleServiceImpl.java index 79e5c50a..f6bf1fe1 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTAdminRuleServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTAdminRuleServiceImpl.java @@ -5,6 +5,7 @@ package org.geoserver.geofence.services.rest.impl; +import java.net.URI; import java.util.List; import org.geoserver.geofence.core.model.AdminRule; @@ -27,19 +28,21 @@ import org.geoserver.geofence.services.rest.model.RESTRulePosition.RulePosition; import org.geoserver.geofence.services.rest.RESTAdminRuleService; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RestController; + /** * * @author ETj (etj at geo-solutions.it) */ + +@RestController("restAdminRuleService") public class RESTAdminRuleServiceImpl extends BaseRESTServiceImpl implements RESTAdminRuleService { @@ -62,7 +65,7 @@ public RESTOutputAdminRule get(Long id) throws BadRequestRestEx, NotFoundRestEx, @Override @Transactional(propagation = Propagation.REQUIRED, value = "geofenceTransactionManager") - public Response insert(RESTInputAdminRule inputAdminRule) throws NotFoundRestEx, BadRequestRestEx, InternalErrorRestEx { + public ResponseEntity insert(RESTInputAdminRule inputAdminRule) throws NotFoundRestEx, BadRequestRestEx, InternalErrorRestEx { if (inputAdminRule.getPosition() == null || inputAdminRule.getPosition().getPosition() == null) { throw new BadRequestRestEx("Bad position: " + inputAdminRule.getPosition()); @@ -83,7 +86,10 @@ public Response insert(RESTInputAdminRule inputAdminRule) throws NotFoundRestEx, try { Long id = adminRuleAdminService.insert(rule, position); - return Response.status(Status.CREATED).tag(id.toString()).entity(id).build(); + return ResponseEntity + .created(URI.create(id.toString())) + .eTag(id.toString()) + .body(id); } catch (BadRequestServiceEx ex) { LOGGER.error(ex.getMessage()); throw new BadRequestRestEx(ex.getMessage()); @@ -155,15 +161,15 @@ public void update(Long id, RESTInputAdminRule rule) throws BadRequestRestEx, No } @Override - public Response delete(Long id) throws NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(Long id) throws NotFoundRestEx, InternalErrorRestEx { try { if (!adminRuleAdminService.delete(id)) { LOGGER.warn("Rule not found: " + id); throw new NotFoundRestEx("Rule not found: " + id); } - return Response.status(Status.OK).entity("OK\n").build(); - + return ResponseEntity.ok("OK\n"); + } catch (GeoFenceRestEx ex) { // already handled throw ex; } catch (NotFoundServiceEx ex) { diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTBatchServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTBatchServiceImpl.java index 89247a2f..87306ba8 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTBatchServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTBatchServiceImpl.java @@ -21,19 +21,20 @@ import org.geoserver.geofence.services.rest.model.RESTInputInstance; import org.geoserver.geofence.services.rest.model.RESTInputRule; import org.geoserver.geofence.services.rest.model.RESTInputUser; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.springframework.beans.factory.InitializingBean; +import org.springframework.http.ResponseEntity; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RestController; /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restBatchService") public class RESTBatchServiceImpl extends BaseRESTServiceImpl implements InitializingBean, RESTBatchService @@ -56,9 +57,10 @@ public class RESTBatchServiceImpl @Transactional(value="geofenceTransactionManager") @Override - public Response exec(RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity exec(RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx { runBatch(batch); - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); + } public void runBatch(RESTBatch batch) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx { diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTConfigServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTConfigServiceImpl.java index daf53ce2..560b8bb2 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTConfigServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTConfigServiceImpl.java @@ -58,12 +58,14 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.springframework.web.bind.annotation.RestController; /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restConfigService") public class RESTConfigServiceImpl implements RESTConfigService { private static final Logger LOGGER = LogManager.getLogger(RESTConfigServiceImpl.class); @@ -239,7 +241,7 @@ public void cleanup() throws InternalErrorRestEx { /** - * @deprecated misbehaves since usergroups introduction. Please use backup() + * @Deprecated misbehaves since usergroups introduction. Please use backup() */ @Override public RESTFullConfiguration getConfiguration(Boolean includeGRUsers) { diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTInstanceServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTInstanceServiceImpl.java index ef1acf44..f0c3b21a 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTInstanceServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTInstanceServiceImpl.java @@ -5,6 +5,7 @@ package org.geoserver.geofence.services.rest.impl; +import java.net.URI; import java.util.List; import org.geoserver.geofence.core.model.GSInstance; @@ -25,17 +26,17 @@ import org.geoserver.geofence.services.rest.model.RESTOutputInstance; import org.geoserver.geofence.services.rest.model.RESTShortInstanceList; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; - import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restInstanceService") public class RESTInstanceServiceImpl extends BaseRESTServiceImpl implements RESTGSInstanceService { @@ -83,7 +84,7 @@ public RESTOutputInstance get(String name) throws NotFoundRestEx, InternalErrorR } @Override - public Response insert(RESTInputInstance instance) throws NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { + public ResponseEntity insert(RESTInputInstance instance) throws NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { // check that no group with same name exists boolean exists; @@ -112,8 +113,11 @@ public Response insert(RESTInputInstance instance) throws NotFoundRestEx, Intern insert.setPassword(instance.getPassword()); Long id = instanceAdminService.insert(insert); - return Response.status(Status.CREATED).tag(id.toString()).entity(id).build(); - + return ResponseEntity + .created(URI.create(id.toString())) + .eTag(id.toString()) + .body(id); + } catch (Exception ex) { LOGGER.error(ex.getMessage(), ex); throw new InternalErrorRestEx(ex.getMessage()); @@ -175,7 +179,7 @@ public void update(Long id, RESTInputInstance instance) throws BadRequestRestEx, } @Override - public Response delete(Long id, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(Long id, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { try { if ( cascade ) { ruleAdminService.deleteRulesByInstance(id); @@ -194,7 +198,7 @@ public Response delete(Long id, boolean cascade) throws ConflictRestEx, NotFound throw new NotFoundRestEx("GSInstance not found: " + id); } - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); } catch (GeoFenceRestEx ex) { // already handled throw ex; @@ -208,12 +212,13 @@ public Response delete(Long id, boolean cascade) throws ConflictRestEx, NotFound } @Override - public Response delete(String name, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(String name, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { try { long id = instanceAdminService.get(name).getId(); this.delete(id, cascade); - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); + } catch (NotFoundServiceEx ex) { LOGGER.warn("GSInstance not found: " + name); throw new NotFoundRestEx("GSInstance not found: " + name); diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImpl.java index ba4ec507..111cc03b 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImpl.java @@ -5,12 +5,10 @@ package org.geoserver.geofence.services.rest.impl; +import java.net.URI; import java.util.HashSet; import java.util.List; 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.locationtech.jts.geom.Geometry; import org.locationtech.jts.geom.MultiPolygon; @@ -53,11 +51,16 @@ import java.util.Arrays; import java.util.ArrayList; import java.util.Comparator; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restRuleService") +@ResponseBody public class RESTRuleServiceImpl extends BaseRESTServiceImpl implements RESTRuleService { @@ -87,7 +90,7 @@ public RESTOutputRule get(Long id) throws BadRequestRestEx, NotFoundRestEx, Inte @Override @Transactional(propagation = Propagation.REQUIRED, value = "geofenceTransactionManager") - public Response insert(RESTInputRule inputRule) throws NotFoundRestEx, BadRequestRestEx, InternalErrorRestEx { + public ResponseEntity insert(RESTInputRule inputRule) throws NotFoundRestEx, BadRequestRestEx, InternalErrorRestEx { if (inputRule.getPosition() == null || inputRule.getPosition().getPosition() == null) { throw new BadRequestRestEx("Bad position: " + inputRule.getPosition()); @@ -113,7 +116,11 @@ public Response insert(RESTInputRule inputRule) throws NotFoundRestEx, BadReques ruleAdminService.setDetails(id, details); } - return Response.status(Status.CREATED).tag(id.toString()).entity(id).build(); + return ResponseEntity + .created(URI.create(id.toString())) + .eTag(id.toString()) + .body(id); + } catch (BadRequestServiceEx ex) { LOGGER.error(ex.getMessage()); throw new BadRequestRestEx(ex.getMessage()); @@ -316,14 +323,14 @@ public void update(Long id, RESTInputRule rule) throws BadRequestRestEx, NotFoun } @Override - public Response delete(Long id) throws NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(Long id) throws NotFoundRestEx, InternalErrorRestEx { try { if (!ruleAdminService.delete(id)) { LOGGER.warn("Rule not found: " + id); throw new NotFoundRestEx("Rule not found: " + id); } - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); } catch (GeoFenceRestEx ex) { // already handled throw ex; @@ -434,27 +441,27 @@ private void setFilter(TextFilter filter, String name, Boolean includeDefault) { } @Override - public long count( - String userName, Boolean userDefault, - String roleName, Boolean groupDefault, - Long instanceId, String instanceName, Boolean instanceDefault, - String serviceName, Boolean serviceDefault, - String requestName, Boolean requestDefault, - String workspace, Boolean workspaceDefault, - String layer, Boolean layerDefault) + public Long count( + String userName, Boolean userAny, + String groupName, Boolean groupAny, + Long instanceId, String instanceName, Boolean instanceAny, + String serviceName, Boolean serviceAny, + String requestName, Boolean requestAny, + String workspace, Boolean workspaceAny, + String layer, Boolean layerAny) throws BadRequestRestEx, InternalErrorRestEx { RuleFilter filter = buildFilter( - userName, userDefault, - roleName, groupDefault, - instanceId, instanceName, instanceDefault, - serviceName, serviceDefault, - requestName, requestDefault, - workspace, workspaceDefault, - layer, layerDefault); + userName, userAny, + groupName, groupAny, + instanceId, instanceName, instanceAny, + serviceName, serviceAny, + requestName, requestAny, + workspace, workspaceAny, + layer, layerAny); try { - return ruleAdminService.count(filter); + return (Long)ruleAdminService.count(filter); } catch (Exception ex) { LOGGER.error(ex); throw new InternalErrorRestEx(ex.getMessage()); @@ -463,7 +470,7 @@ public long count( } @Override - public Response move(String rulesIds, Integer targetPriority) + public ResponseEntity move(String rulesIds, Integer targetPriority) throws BadRequestRestEx, InternalErrorRestEx { try { @@ -480,7 +487,8 @@ public Response move(String rulesIds, Integer targetPriority) priority++; } } - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); + } catch (Exception ex) { LOGGER.error(ex.getMessage(), ex); throw new InternalErrorRestEx(ex.getMessage()); @@ -573,7 +581,8 @@ protected Rule fromInput(RESTInputRule in) { rule.setInstance(getInstance(in.getInstance())); } - if(StringUtils.isNotBlank(in.getIpaddress())) { + String ip = in.getIpaddress(); + if(ip != null && ! ip.isBlank()) { rule.setAddressRange(new IPAddressRange(in.getIpaddress())); } diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImpl.java index 7608d962..4f271199 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImpl.java @@ -5,6 +5,7 @@ package org.geoserver.geofence.services.rest.impl; +import java.net.URI; import java.util.List; import org.geoserver.geofence.core.model.UserGroup; @@ -21,17 +22,18 @@ import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; import org.geoserver.geofence.services.rest.model.RESTInputGroup; import org.geoserver.geofence.services.rest.model.config.RESTFullUserGroupList; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restUserGroupService") public class RESTUserGroupServiceImpl extends BaseRESTServiceImpl implements RESTUserGroupService { @@ -65,7 +67,7 @@ public ShortGroup get(String name) throws NotFoundRestEx, InternalErrorRestEx { } @Override - public Response insert(RESTInputGroup userGroup) throws NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { + public ResponseEntity insert(RESTInputGroup userGroup) throws NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { // check that no group with same name exists boolean exists; @@ -92,7 +94,11 @@ public Response insert(RESTInputGroup userGroup) throws NotFoundRestEx, Internal insert.setName(userGroup.getName()); Long id = userGroupAdminService.insert(insert); - return Response.status(Status.CREATED).tag(id.toString()).entity(id).build(); + + return ResponseEntity + .created(URI.create(id.toString())) + .eTag(id.toString()) + .body(id); } catch (Exception ex) { LOGGER.error(ex.getMessage(), ex); @@ -140,7 +146,7 @@ public void update(String name, RESTInputGroup group) throws BadRequestRestEx, N } @Override - public Response delete(String name, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(String name, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { try { if ( cascade ) { ruleAdminService.deleteRulesByRole(name); @@ -161,7 +167,7 @@ public Response delete(String name, boolean cascade) throws ConflictRestEx, NotF throw new NotFoundRestEx("Role not found: " + name); } - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); } catch (GeoFenceRestEx ex) { // already handled throw ex; diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImpl.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImpl.java index 021d84ad..ba28b1c7 100644 --- a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImpl.java +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImpl.java @@ -5,16 +5,20 @@ package org.geoserver.geofence.services.rest.impl; +import java.net.URI; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.geoserver.geofence.core.model.GSUser; +import org.geoserver.geofence.core.model.UserGroup; + import org.geoserver.geofence.services.rest.exception.ConflictRestEx; import org.geoserver.geofence.services.rest.exception.GeoFenceRestEx; import org.geoserver.geofence.services.rest.exception.BadRequestRestEx; import org.geoserver.geofence.services.rest.exception.InternalErrorRestEx; import org.geoserver.geofence.services.rest.exception.NotFoundRestEx; -import java.util.List; - - -import org.geoserver.geofence.core.model.GSUser; -import org.geoserver.geofence.core.model.UserGroup; import org.geoserver.geofence.services.dto.RuleFilter; import org.geoserver.geofence.services.dto.RuleFilter.SpecialFilterType; import org.geoserver.geofence.services.exception.BadRequestServiceEx; @@ -25,58 +29,54 @@ import org.geoserver.geofence.services.rest.model.RESTShortUser; import org.geoserver.geofence.services.rest.model.RESTShortUserList; import org.geoserver.geofence.services.rest.model.util.IdName; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; -import javax.ws.rs.core.Response; -import javax.ws.rs.core.Response.Status; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.RestController; + /** * * @author ETj (etj at geo-solutions.it) */ +@RestController("restUserService") public class RESTUserServiceImpl extends BaseRESTServiceImpl implements RESTUserService { private static final Logger LOGGER = LogManager.getLogger(RESTUserServiceImpl.class); -// private UserAdminService userAdminService; -// private UserGroupAdminService userGroupAdminService; - @Override - public Response delete(String username, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { + public ResponseEntity delete(String name, boolean cascade) throws ConflictRestEx, NotFoundRestEx, InternalErrorRestEx { try { if ( cascade ) { - ruleAdminService.deleteRulesByUser(username); + ruleAdminService.deleteRulesByUser(name); } else { RuleFilter filter = new RuleFilter(SpecialFilterType.ANY); - filter.setUser(username); + filter.setUser(name); filter.getUser().setIncludeDefault(false); long cnt = ruleAdminService.count(filter); if ( cnt > 0 ) { - throw new ConflictRestEx("Existing rules reference the user " + username); + throw new ConflictRestEx("Existing rules reference the user " + name); } } - GSUser user = userAdminService.getFull(username); // may throw NotFoundServiceEx + GSUser user = userAdminService.getFull(name); // may throw NotFoundServiceEx if ( ! userAdminService.delete(user.getId())) { LOGGER.warn("ILLEGAL STATE -- User not found: " + user); // this should not happen throw new NotFoundRestEx("ILLEGAL STATE -- User not found: " + user); } - return Response.status(Status.OK).entity("OK\n").build(); + return ResponseEntity.ok("OK\n"); } catch (GeoFenceRestEx ex) { // already handled throw ex; } catch (NotFoundServiceEx ex) { - LOGGER.warn("User not found: " + username); - throw new NotFoundRestEx("User not found: " +username); + LOGGER.warn("User not found: " + name); + throw new NotFoundRestEx("User not found: " +name); } catch (Exception ex) { LOGGER.error(ex.getMessage(), ex); throw new InternalErrorRestEx(ex.getMessage()); @@ -98,7 +98,7 @@ public RESTOutputUser get(String name) throws NotFoundRestEx, InternalErrorRestE } @Override - public Response insert(RESTInputUser user) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { + public ResponseEntity insert(RESTInputUser user) throws BadRequestRestEx, NotFoundRestEx, InternalErrorRestEx, ConflictRestEx { boolean exists; @@ -147,9 +147,12 @@ public Response insert(RESTInputUser user) throws BadRequestRestEx, NotFoundRest u.setFullName(user.getFullName()); u.setEmailAddress(user.getEmailAddress()); - Long ret = userAdminService.insert(u); + Long id = userAdminService.insert(u); - return Response.status(Status.CREATED).tag(ret.toString()).entity(ret).build(); + return ResponseEntity + .created(URI.create(id.toString())) + .eTag(id.toString()) + .body(id); } catch (GeoFenceRestEx ex) { // already handled @@ -253,8 +256,13 @@ public RESTShortUserList getList(String nameLike, Integer page, Integer entries) } @Override - public long count(String nameLike) { - return userAdminService.getCount(nameLike); + public Long count(String nameLike) { + try { + return userAdminService.getCount(nameLike); + } catch (Exception ex) { + LOGGER.warn("Unexpected exception", ex); + throw new RuntimeException(ex); + } } // ========================================================================== diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/LongHttpMessageConverter.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/LongHttpMessageConverter.java new file mode 100644 index 00000000..098517f6 --- /dev/null +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/LongHttpMessageConverter.java @@ -0,0 +1,62 @@ +/* + */ +package org.geoserver.geofence.services.rest.impl.converters; + +import java.io.IOException; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.lang.Nullable; +import org.springframework.util.Assert; +import org.springframework.util.StreamUtils; + +/** + * + * @author geosol + */ +public class LongHttpMessageConverter extends AbstractHttpMessageConverter implements HttpMessageConverter { + + public static final Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + public LongHttpMessageConverter() { + super(DEFAULT_CHARSET, MediaType.TEXT_PLAIN); + } + + @Override + public boolean supports(Class clazz) { + return Long.class == clazz; + } + + @Override + protected Long readInternal(Class clazz, HttpInputMessage inputMessage) + throws IOException, HttpMessageNotReadableException { + + Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); + String asString = StreamUtils.copyToString(inputMessage.getBody(), charset); + return Long.parseLong(asString); + } + + @Override + protected void writeInternal(Long t, HttpOutputMessage outputMessage) + throws IOException, HttpMessageNotWritableException { + Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType()); + StreamUtils.copy(t.toString(), charset, outputMessage.getBody()); + } + + private Charset getContentTypeCharset(@Nullable MediaType contentType) { + if (contentType != null && contentType.getCharset() != null) { + return contentType.getCharset(); + } else { + Charset charset = getDefaultCharset(); + Assert.state(charset != null, "No default charset"); + return charset; + } + } + +} diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertConfigurator.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertConfigurator.java new file mode 100644 index 00000000..eb3cb654 --- /dev/null +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertConfigurator.java @@ -0,0 +1,36 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.geoserver.geofence.services.rest.impl.converters; + +import java.util.List; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.HttpMessageConverter; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * + * @author geosol + */ + +@EnableWebMvc +@Configuration +@ComponentScan(basePackageClasses = MessageConvertConfigurator.class) +public class MessageConvertConfigurator implements WebMvcConfigurer { + + private static final Logger LOGGER = LogManager.getLogger(MessageConvertConfigurator.class); + + @Override + public void extendMessageConverters(List> converters) { + LOGGER.info("*** Adding converter " + LongHttpMessageConverter.class.getSimpleName()); + converters.add(new LongHttpMessageConverter()); + } + + +} \ No newline at end of file diff --git a/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertPrinter.java b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertPrinter.java new file mode 100644 index 00000000..190fe381 --- /dev/null +++ b/src/extension/rest/impl/src/main/java/org/geoserver/geofence/services/rest/impl/converters/MessageConvertPrinter.java @@ -0,0 +1,35 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.geoserver.geofence.services.rest.impl.converters; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.event.ContextRefreshedEvent; +import org.springframework.context.event.EventListener; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; + +/** + * + * @author geosol + */ +//@EnableWebMvc +@Configuration +public class MessageConvertPrinter { + + private static final Logger LOGGER = LogManager.getLogger(MessageConvertPrinter.class); + + @Autowired + private RequestMappingHandlerAdapter handlerAdapter; + + @EventListener + public void handleContextRefresh(ContextRefreshedEvent event) { + handlerAdapter.getMessageConverters().stream() + .map(c -> c.toString()) + .forEach(LOGGER::info); + } +} diff --git a/src/extension/rest/impl/src/main/resources/applicationContext.xml b/src/extension/rest/impl/src/main/resources/applicationContext.xml index 4a073502..4a6da2d5 100644 --- a/src/extension/rest/impl/src/main/resources/applicationContext.xml +++ b/src/extension/rest/impl/src/main/resources/applicationContext.xml @@ -8,184 +8,24 @@ - - - - - - + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTBaseTest.java b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTBaseTest.java index fa15588f..251af498 100644 --- a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTBaseTest.java +++ b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTBaseTest.java @@ -20,50 +20,41 @@ import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; -import org.springframework.context.support.ClassPathXmlApplicationContext; import static org.junit.Assert.*; import org.junit.rules.TestName; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; +import org.springframework.test.context.web.WebAppConfiguration; +import org.springframework.web.context.WebApplicationContext; /** * * @author ETj (etj at geo-solutions.it) */ +@RunWith(SpringJUnit4ClassRunner.class) +@WebAppConfiguration("classpath*:applicationContext.xml") +@ContextConfiguration(locations = "classpath*:applicationContext.xml") public abstract class RESTBaseTest { private static final Logger LOGGER = LogManager.getLogger(RESTBaseTest.class); - - @org.junit.Rule public TestName name = new TestName(); - - protected static ClassPathXmlApplicationContext ctx = null; - - protected static RESTUserService restUserService; - protected static RESTUserGroupService restUserGroupService; - protected static RESTRuleService restRuleService; + + @org.junit.Rule + public TestName name = new TestName(); + + @Autowired + protected WebApplicationContext ctx; + + @Autowired + protected RESTUserService restUserService; + + @Autowired + protected RESTUserGroupService restUserGroupService; + + @Autowired + protected RESTRuleService restRuleService; public RESTBaseTest() { - - synchronized(RESTBaseTest.class) { - if(ctx == null) { - String[] paths = { - "classpath*:applicationContext.xml" -// ,"applicationContext-test.xml" - }; - ctx = new ClassPathXmlApplicationContext(paths); - - - for(String name : ctx.getBeanDefinitionNames()) { - if(name.startsWith("rest") ) - LOGGER.warn(" BEAN ===> " + name); - } - - restUserService = (RESTUserService)ctx.getBean("restUserService"); - restUserGroupService = (RESTUserGroupService)ctx.getBean("restUserGroupService"); - restRuleService = (RESTRuleService)ctx.getBean("restRuleService"); - } - - assertNotNull(restUserService); - assertNotNull(restUserGroupService); - assertNotNull(restRuleService); - } } @BeforeClass @@ -80,6 +71,12 @@ public void before() throws Exception { LOGGER.info("============================== TEST " + name.getMethodName()); LOGGER.info(""); + assertNotNull("CTX not set", ctx); + assertNotNull("restUserService not set", restUserService); + assertNotNull("restUserGroupService not set", restUserGroupService); + assertNotNull("restRuleService not set", restRuleService); + + RESTOutputRuleList rules = restRuleService.get(null, null, false, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null); for (RESTOutputRule rule : rules) { LOGGER.warn("Removing " + rule); diff --git a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImplTest.java b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImplTest.java index 4a5dff44..18e7fbce 100644 --- a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImplTest.java +++ b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTRuleServiceImplTest.java @@ -18,13 +18,14 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; -import javax.ws.rs.core.Response; + import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.geoserver.geofence.services.rest.model.RESTRulePosition; import org.junit.Test; import static org.junit.Assert.*; +import org.springframework.http.ResponseEntity; /** * @@ -38,8 +39,8 @@ public class RESTRuleServiceImplTest extends RESTBaseTest { public void testInsert() { RESTInputGroup group = new RESTInputGroup(); group.setName("g1"); - Response res = restUserGroupService.insert(group); - long gid1 = (Long)res.getEntity(); + ResponseEntity res = restUserGroupService.insert(group); + long gid1 = (Long)res.getBody(); RESTInputUser user = new RESTInputUser(); @@ -47,14 +48,14 @@ public void testInsert() { user.setEnabled(Boolean.TRUE); user.setGroups(new ArrayList()); user.getGroups().add(new IdName("g1")); - Response userResp = restUserService.insert(user); - Long id = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + Long id = (Long)userResp.getBody(); RESTInputRule rule = new RESTInputRule(); rule.setUsername("user0"); try{ - restRuleService.insert(rule).getEntity(); + restRuleService.insert(rule).getBody(); fail("Missing position not trapped"); } catch (BadRequestRestEx e) { LOGGER.info("Exception properly trapped"); @@ -63,7 +64,7 @@ public void testInsert() { rule.setPosition(new RESTRulePosition(RESTRulePosition.RulePosition.offsetFromTop, 0)); rule.setGrant(GrantType.ALLOW); - Long rid = (Long)restRuleService.insert(rule).getEntity(); + Long rid = (Long)restRuleService.insert(rule).getBody(); assertNotNull(rid); { @@ -85,13 +86,13 @@ public void testMissingLayerOnConstraints() { rule.setConstraints(constraints); try { - restRuleService.insert(rule).getEntity(); + restRuleService.insert(rule).getBody(); fail("Missing layer not trapped"); } catch (BadRequestRestEx e) { LOGGER.info("Exception properly trapped"); } rule.setLayer("l0"); - Long rid = (Long)restRuleService.insert(rule).getEntity(); + Long rid = restRuleService.insert(rule).getBody(); assertNotNull(rid); } @@ -103,7 +104,7 @@ public void testUpdateToNull() { rule.setService("s0"); rule.setWorkspace("w0"); rule.setLayer("l0"); - Long rid = (Long)restRuleService.insert(rule).getEntity(); + Long rid = restRuleService.insert(rule).getBody(); assertNotNull(rid); { @@ -134,7 +135,7 @@ public void testEmptyDetails() { rule.setPosition(new RESTRulePosition(RESTRulePosition.RulePosition.offsetFromTop, 0)); rule.setGrant(GrantType.ALLOW); rule.setLayer("l0"); - Long rid = (Long)restRuleService.insert(rule).getEntity(); + Long rid = (Long)restRuleService.insert(rule).getBody(); assertNotNull(rid); { @@ -177,7 +178,7 @@ public void testDetails() { constraints.setAllowedStyles(new HashSet(Arrays.asList("s1","s2"))); rule.setConstraints(constraints); - rid = (Long)restRuleService.insert(rule).getEntity(); + rid = (Long)restRuleService.insert(rule).getBody(); assertNotNull(rid); } @@ -234,7 +235,7 @@ public void testAttribs() { ))); rule.setConstraints(constraints); - rid = (Long)restRuleService.insert(rule).getEntity(); + rid = (Long)restRuleService.insert(rule).getBody(); assertNotNull(rid); } diff --git a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImplTest.java b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImplTest.java index 981d12c1..570c48b6 100644 --- a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImplTest.java +++ b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserGroupServiceImplTest.java @@ -11,12 +11,12 @@ import org.geoserver.geofence.services.rest.model.RESTOutputUser; import org.geoserver.geofence.services.rest.model.util.IdName; import java.util.ArrayList; -import javax.ws.rs.core.Response; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.junit.Test; import static org.junit.Assert.*; +import org.springframework.http.ResponseEntity; /** * @@ -29,8 +29,8 @@ public class RESTUserGroupServiceImplTest extends RESTBaseTest { public void testInsert() { RESTInputGroup group = new RESTInputGroup(); group.setName("g1"); - Response res = restUserGroupService.insert(group); - long gid1 = (Long)res.getEntity(); + ResponseEntity res = restUserGroupService.insert(group); + long gid1 = (Long)res.getBody(); RESTInputUser user = new RESTInputUser(); user.setName("user0"); @@ -38,8 +38,8 @@ public void testInsert() { user.setGroups(new ArrayList()); user.getGroups().add(new IdName("g1")); - Response userResp = restUserService.insert(user); - Long id = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + Long id = (Long)userResp.getBody(); { RESTOutputUser out = restUserService.get("user0"); diff --git a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImplTest.java b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImplTest.java index d1179f32..9a09f0f5 100644 --- a/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImplTest.java +++ b/src/extension/rest/impl/src/test/java/org/geoserver/geofence/services/rest/impl/RESTUserServiceImplTest.java @@ -14,12 +14,12 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; -import javax.ws.rs.core.Response; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.junit.Test; import static org.junit.Assert.*; +import org.springframework.http.ResponseEntity; /** * @@ -33,8 +33,8 @@ public class RESTUserServiceImplTest extends RESTBaseTest { public void testInsert() { RESTInputGroup group = new RESTInputGroup(); group.setName("g1"); - Response res = restUserGroupService.insert(group); - long gid1 = (Long)res.getEntity(); + ResponseEntity res = restUserGroupService.insert(group); + long gid1 = (Long)res.getBody(); RESTInputUser user = new RESTInputUser(); @@ -43,8 +43,8 @@ public void testInsert() { user.setGroups(new ArrayList()); user.getGroups().add(new IdName("g1")); - Response userResp = restUserService.insert(user); - Long id = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + Long id = (Long)userResp.getBody(); { RESTOutputUser out = restUserService.get("user0"); @@ -58,8 +58,8 @@ public void testInsert() { public void testInsertDup() { RESTInputGroup group = new RESTInputGroup(); group.setName("g1"); - Response res = restUserGroupService.insert(group); - long gid1 = (Long)res.getEntity(); + ResponseEntity res = restUserGroupService.insert(group); + long gid1 = (Long)res.getBody(); { RESTInputUser user = new RESTInputUser(); @@ -68,8 +68,8 @@ public void testInsertDup() { user.setGroups(new ArrayList()); user.getGroups().add(new IdName("g1")); - Response userResp = restUserService.insert(user); - Long id = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + Long id = (Long)userResp.getBody(); } LOGGER.info("Inserting dup"); @@ -81,8 +81,8 @@ public void testInsertDup() { user.getGroups().add(new IdName("g1")); try { - Response userResp = restUserService.insert(user); - Long id = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + Long id = (Long)userResp.getBody(); fail("409 not trapped"); } catch(ConflictRestEx e) { LOGGER.info("Exception properly trapped"); @@ -96,8 +96,8 @@ public void testUpdateGroup() { for(String name: Arrays.asList("g1","g2","g3","g4")) { RESTInputGroup group1 = new RESTInputGroup(); group1.setName(name); - Response res = restUserGroupService.insert(group1); - long gid1 = (Long)res.getEntity(); + ResponseEntity res = restUserGroupService.insert(group1); + long gid1 = (Long)res.getBody(); LOGGER.info("Created group id:"+gid1 + " name:"+name); } } @@ -113,8 +113,8 @@ public void testUpdateGroup() { user.setGroups(new ArrayList()); user.getGroups().add(new IdName("g1")); - Response userResp = restUserService.insert(user); - uid = (Long)userResp.getEntity(); + ResponseEntity userResp = restUserService.insert(user); + uid = (Long)userResp.getBody(); } { // check user diff --git a/src/extension/rest/impl/src/test/resources/applicationContext.xml b/src/extension/rest/impl/src/test/resources/applicationContext.xml index 4fbbc1aa..21e9d5ac 100644 --- a/src/extension/rest/impl/src/test/resources/applicationContext.xml +++ b/src/extension/rest/impl/src/test/resources/applicationContext.xml @@ -10,21 +10,18 @@ + + - - - - - contextConfigLocation - + + + + + contextConfigLocation + classpath*:applicationContext.xml - + - - - + @@ -36,20 +36,20 @@ - - - CXFServlet - org.apache.cxf.transport.servlet.CXFServlet - + + + CXFServlet + org.apache.cxf.transport.servlet.CXFServlet + - - CXFServlet - /rest/* - + + CXFServlet + /rest/* + - - - Application.html - + + + Application.html + diff --git a/src/web/src/main/resources/applicationContext.xml b/src/web/src/main/resources/applicationContext.xml index f6308651..4e8c7ed6 100644 --- a/src/web/src/main/resources/applicationContext.xml +++ b/src/web/src/main/resources/applicationContext.xml @@ -5,25 +5,21 @@ */ --> - + + + @@ -42,7 +38,10 @@ jdbc:h2:/tmp/ftpusers jdbc:h2:/tmp/gbusers - + + classpath*:/applicationContext-common.xml + classpath:applicationContext-client.xml + --> @@ -82,10 +81,4 @@ - - - - - - \ No newline at end of file