diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java b/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java index b78cccd..4c1808b 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/GeonetworkResolver.java @@ -57,7 +57,7 @@ import org.w3c.dom.Document; * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) * Oct 23, 2018 */ -@Path("/geonetwork") +@Path("geonetwork") public class GeonetworkResolver { private static Logger logger = LoggerFactory.getLogger(GeonetworkResolver.class); @@ -70,7 +70,7 @@ public class GeonetworkResolver { private static final String PATH_PARAM_SCOPE = "scope"; public static final String CSW_SERVER = "srv/en/csw"; - public static final String PATH_PARAM_REQUEST_DELIMITIER = "/$$"; + public static final String VALUE_OF_REQUEST_DELIMITIER = "$$"; public static final String PATH_PARAM_REMAINING = "remainPath"; public static final String QUERY_PARAM_RESET_CACHE_PARAM = "resetcache"; @@ -82,15 +82,15 @@ public class GeonetworkResolver { protected Map cacheGNInstances; - private String help = "https://wiki.gcube-system.org/gcube/URI_Resolver#GIS_Resolver"; + private String help = "https://wiki.gcube-system.org/gcube/GCube_Resource_Catalogue#Geonetwork_Resolver"; /** * Gets the geonetwork request criteria. * Creates a request criteria from input parameter pathWithoutGN * The parameter pathWithoutGN should be an ordered string (like REST request): - * MODE/SCOPE/VISIBILITY/OWNER/$$ - * MODE must be: {@link MODE} + * SCOPE/MODE/VISIBILITY/OWNER/$$ * SCOPE must be: ROOT|VO|VRE + * MODE must be: {@link MODE} * VISIBILITY must be: {@link VISIBILITY} * OWNER (is optional): filter by owner * @@ -105,55 +105,57 @@ public class GeonetworkResolver { * @return the geonetwork request criteria */ -// /* (non-Javadoc) -// * @see javax.servlet.GenericServlet#init() -// */ -// @Override -// public void init() throws ServletException { -// super.init(); -// timer = new Timer(true); -// timer.schedule(new TimerTask() { -// @Override -// public void run() { -// logger.info("Resetting Geonetwork configuratiors cache..."); -// purgeCacheGeonetworkInstances(); -// } -// }, CACHE_RESET_DELAY, CACHE_RESET_TIME); -// } - @GET - @Path("{"+PATH_PARAM_MODE+"}/{"+PATH_PARAM_SCOPE+"}/{"+PATH_PARAM_VISIBILITY+"}/{"+PATH_PARAM_OWNER+"}/{"+PATH_PARAM_REQUEST_DELIMITER+"}") + @Path("/{"+PATH_PARAM_SCOPE+":([^/?$]+)?}/{"+PATH_PARAM_MODE+"}/{"+PATH_PARAM_VISIBILITY+"}/{"+PATH_PARAM_OWNER+":([^/?$]+)?}/{"+PATH_PARAM_REQUEST_DELIMITER+"}{remainPath:(/[^/?$]+)?}") public Response submitGet(@Context HttpServletRequest req, - @PathParam(PATH_PARAM_MODE) MODE mode, - @PathParam(PATH_PARAM_SCOPE) String scope, - @PathParam(PATH_PARAM_VISIBILITY) VISIBILITY visibility, + @PathParam(PATH_PARAM_SCOPE) @Nullable String scope, + @PathParam(PATH_PARAM_MODE) @Nullable String mode, + @PathParam(PATH_PARAM_VISIBILITY) @Nullable String visibility, @PathParam(PATH_PARAM_OWNER) @Nullable String owner, - @PathParam(PATH_PARAM_REQUEST_DELIMITER) String requestDelimiter, - @QueryParam(QUERY_PARAM_RESET_CACHE_PARAM) String resetCache, - @QueryParam(QUERY_PARAM_RESET_CACHED_SCOPE_PARAM) String resetScope) { - logger.info(this.getClass().getSimpleName()+" GET starts..."); + @PathParam(PATH_PARAM_REQUEST_DELIMITER) @Nullable String requestDelimiter, + @PathParam("remainPath") @Nullable String remainPath, + @QueryParam(QUERY_PARAM_RESET_CACHE_PARAM) @Nullable String resetCache, + @QueryParam(QUERY_PARAM_RESET_CACHED_SCOPE_PARAM) @Nullable String resetScope) { - //Checking mandatory parameters - if(mode==null){ - logger.error("Path Parameter 'mode' not found"); - ExceptionManager.throwBadRequestException(req, "Missing mandatory path parameter 'mode' as value "+MODE.values(), GeonetworkResolver.class, help); - } + logger.info(this.getClass().getSimpleName()+" GET starts..."); + logger.info("Params are [mode: "+mode+", scope: "+scope+", visibility: "+visibility+", owner: "+owner+", requestDelimiter: "+requestDelimiter+", remainPath: "+remainPath+"]"); if(scope==null || scope.isEmpty()){ logger.error("Path Parameter 'scope' not found"); ExceptionManager.throwBadRequestException(req, "Missing mandatory path parameter 'scope'", GeonetworkResolver.class, help); } + if(mode==null || mode.isEmpty()){ + logger.error("Path Parameter 'scope' not found"); + ExceptionManager.throwBadRequestException(req, "Missing mandatory path parameter 'mode'", GeonetworkResolver.class, help); + } + + mode = mode.toUpperCase(); + try{ + MODE.valueOf(mode); + }catch(Exception e){ + List toPrint = Arrays.asList(MODE.values()); + logger.error("The 'mode' parameter is wrong, Have you pass a valid parameter MODE like "+toPrint+"?"); + ExceptionManager.throwWrongParameterException(req, "The 'mode' parameter must be value of "+toPrint, GeonetworkResolver.class, help); + } + if(visibility==null){ logger.error("Path Parameter 'visibility' not found"); ExceptionManager.throwBadRequestException(req, "Missing mandatory path parameter 'visibility'", GeonetworkResolver.class, help); } - logger.info("Params are [mode: "+mode+", scope: "+scope+", visibility:"+visibility+", owner:"+owner+"]"); + visibility = visibility.toUpperCase(); + try{ + VISIBILITY.valueOf(visibility); + }catch (Exception e) { + List toPrint = Arrays.asList(VISIBILITY.values()); + logger.error("The 'visibility' parameter is wrong, Have you pass a valid parameter VISIBILITY like "+toPrint+"?"); + ExceptionManager.throwWrongParameterException(req, "The 'visibility' parameter must be value of "+toPrint, GeonetworkResolver.class, help); + } - if(requestDelimiter==null){ - logger.error("Path Parameter to REQUEST_DELIMITIER '"+PATH_PARAM_REQUEST_DELIMITIER+"' not found"); - ExceptionManager.throwBadRequestException(req, "Path Parameter to REQUEST_DELIMITIER '"+PATH_PARAM_REQUEST_DELIMITIER+"' not found", GeonetworkResolver.class, help); + if(requestDelimiter==null || requestDelimiter.compareTo(VALUE_OF_REQUEST_DELIMITIER)!=0){ + logger.error("Path Parameter to REQUEST_DELIMITIER '"+VALUE_OF_REQUEST_DELIMITIER+"' not found"); + ExceptionManager.throwBadRequestException(req, "Path Parameter '"+VALUE_OF_REQUEST_DELIMITIER+"' not found as REQUEST DELIMITER", GeonetworkResolver.class, help); } if(resetCache!=null && Boolean.parseBoolean(resetCache)){ @@ -168,7 +170,6 @@ public class GeonetworkResolver { int index = fullURL.indexOf(GeonetworkRequestFilterParameters.REQUEST_DELIMITIER); int delimiterIndex = index+GeonetworkRequestFilterParameters.REQUEST_DELIMITIER.length(); //BUILDING REMAINING PATH WITHOUT GeonetworkRequestFilterParameters.REQUEST_DELIMITIER - String remainPath = null; if(delimiterIndex toPrint = Arrays.asList(MODE.values()); + logger.error("The 'mode' parameter is wrong, Have you pass a valid parameter MODE like "+toPrint+"?"); + ExceptionManager.throwWrongParameterException(req, "The 'mode' parameter must be value of "+toPrint, GeonetworkResolver.class, help); + } + if(visibility==null){ logger.error("Path Parameter 'visibility' not found"); ExceptionManager.throwBadRequestException(req, "Missing mandatory path parameter 'visibility'", GeonetworkResolver.class, help); } - logger.info("Params are [mode: "+mode+", scope: "+scope+", visibility:"+visibility+", owner:"+owner+"]"); - - if(requestDelimiter==null){ - logger.error("Path Parameter to REQUEST_DELIMITIER '"+PATH_PARAM_REQUEST_DELIMITIER+"' not found"); - ExceptionManager.throwBadRequestException(req, "Path Parameter to REQUEST_DELIMITIER '"+PATH_PARAM_REQUEST_DELIMITIER+"' not found", GeonetworkResolver.class, help); + visibility = visibility.toUpperCase(); + try{ + VISIBILITY.valueOf(visibility); + }catch (Exception e) { + List toPrint = Arrays.asList(VISIBILITY.values()); + logger.error("The 'visibility' parameter is wrong, Have you pass a valid parameter VISIBILITY like "+toPrint+"?"); + ExceptionManager.throwWrongParameterException(req, "The 'visibility' parameter must be value of "+toPrint, GeonetworkResolver.class, help); } - if(resetCache!=null && Boolean.parseBoolean(resetCache)){ - purgeCacheGeonetworkInstances(); - } - - if(resetScope!=null && Boolean.parseBoolean(resetScope)){ - resetGeonetoworkInstanceCacheForScope(scope); + if(requestDelimiter==null || requestDelimiter.compareTo(VALUE_OF_REQUEST_DELIMITIER)!=0){ + logger.error("Path Parameter to REQUEST_DELIMITIER '"+VALUE_OF_REQUEST_DELIMITIER+"' not found"); + ExceptionManager.throwBadRequestException(req, "Path Parameter '"+VALUE_OF_REQUEST_DELIMITIER+"' not found as REQUEST DELIMITER", GeonetworkResolver.class, help); } String fullURL = Util.getFullURL(req); @@ -598,6 +620,9 @@ public class GeonetworkResolver { if(cacheGNInstances==null) purgeCacheGeonetworkInstances(); + if(!scope.startsWith("/")) + scope="/"+scope; + logger.info("Attempt to get geonetwork instance from GeonetworkInstance cache for scope: "+scope); GeonetworkInstance geoInstance = cacheGNInstances.get(scope); diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/error/ExceptionManager.java b/src/main/java/org/gcube/datatransfer/resolver/services/error/ExceptionManager.java index 5912403..ca39fa6 100644 --- a/src/main/java/org/gcube/datatransfer/resolver/services/error/ExceptionManager.java +++ b/src/main/java/org/gcube/datatransfer/resolver/services/error/ExceptionManager.java @@ -10,7 +10,10 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.core.Response.Status; import org.gcube.datatransfer.resolver.services.exceptions.BadRequestException; +import org.gcube.datatransfer.resolver.services.exceptions.ForbiddenRequestException; import org.gcube.datatransfer.resolver.services.exceptions.InternalServerException; +import org.gcube.datatransfer.resolver.services.exceptions.NotAuthorizedRequestException; +import org.gcube.datatransfer.resolver.services.exceptions.NotFoundException; import org.gcube.datatransfer.resolver.services.exceptions.WrongParameterException; @@ -68,6 +71,7 @@ public class ExceptionManager { } + /** * Throw not found exception. * @@ -79,7 +83,7 @@ public class ExceptionManager { public static void throwNotFoundException(HttpServletRequest httpRequest, String errorMessage, Class thrownBy, String helpURI){ URI theURI = checkURI(helpURI); - throw new WrongParameterException(httpRequest, Status.NOT_FOUND, errorMessage, thrownBy, theURI); + throw new NotFoundException(httpRequest, Status.NOT_FOUND, errorMessage, thrownBy, theURI); } @@ -95,7 +99,7 @@ public class ExceptionManager { public static void throwUnauthorizedException(HttpServletRequest httpRequest, String errorMessage, Class thrownBy, String helpURI){ URI theURI = checkURI(helpURI); - throw new WrongParameterException(httpRequest, Status.UNAUTHORIZED, errorMessage, thrownBy, theURI); + throw new NotAuthorizedRequestException(httpRequest, Status.UNAUTHORIZED, errorMessage, thrownBy, theURI); } @@ -111,7 +115,7 @@ public class ExceptionManager { public static void throwForbiddenException(HttpServletRequest httpRequest, String errorMessage, Class thrownBy, String helpURI){ URI theURI = checkURI(helpURI); - throw new WrongParameterException(httpRequest, Status.FORBIDDEN, errorMessage, thrownBy, theURI); + throw new ForbiddenRequestException(httpRequest, Status.FORBIDDEN, errorMessage, thrownBy, theURI); } @@ -126,7 +130,7 @@ public class ExceptionManager { public static URI checkURI(String helpURI){ URI theURI = null; try { - theURI = helpURI==null?new URI(helpURI):null; + theURI = helpURI!=null?new URI(helpURI):null; } catch (URISyntaxException e) { //silent diff --git a/src/main/java/org/gcube/datatransfer/resolver/services/exceptions/NotFoundException.java b/src/main/java/org/gcube/datatransfer/resolver/services/exceptions/NotFoundException.java new file mode 100644 index 0000000..46619ea --- /dev/null +++ b/src/main/java/org/gcube/datatransfer/resolver/services/exceptions/NotFoundException.java @@ -0,0 +1,63 @@ +/** + * + */ +package org.gcube.datatransfer.resolver.services.exceptions; + + +import java.net.URI; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import org.gcube.datatransfer.resolver.Util; +import org.gcube.datatransfer.resolver.services.error.ErrorReport; +import org.gcube.datatransfer.resolver.services.error.ExceptionReport; + + +/** + * The Class NotFoundException. + * + * @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it) + * Oct 23, 2018 + */ +public class NotFoundException extends WebApplicationException { + + + /** + * + */ + private static final long serialVersionUID = 7916339601596360889L; + + + /** + * Instantiates a new not found exception. + * + * @param request the request + * @param httpReturnStatus the http return status + * @param message the message + * @param thrownBySource the thrown by source + * @param help the help + */ + public NotFoundException(HttpServletRequest request, Status httpReturnStatus, String message, Class thrownBySource, URI help) { + + super(Response.status(httpReturnStatus).entity( + ExceptionReport.builder(). + request(Util.getFullURL(request)). + method(request.getMethod()). + success(false). + help(help). + error( + ErrorReport.builder(). + httpErrorCode(Status.NOT_FOUND.getStatusCode()). + name(Status.NOT_FOUND.name()) + .message(message). + thrownBy(thrownBySource.getName()).build()) + .build()) + .type(MediaType.APPLICATION_XML).build()); + + } + +} \ No newline at end of file