diff --git a/pom.xml b/pom.xml index 8c41882..dc67b05 100644 --- a/pom.xml +++ b/pom.xml @@ -10,4 +10,214 @@ 1.0.0-SNAPSHOT war Resource Manager + + + UTF-8 + ${project.basedir}${file.separator}src${file.separator}main${file.separator}webapp${file.separator}WEB-INF + 2.14.0 + + + + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + scm:git:https://code-repo.d4science.org/gCubeSystem/${project.artifactId}.git + https://code-repo.d4science.org/gCubeSystem/${project.artifactId} + + + + + + org.gcube.distribution + gcube-smartgears-bom + 2.5.1-SNAPSHOT + pom + import + + + + + + + org.slf4j + slf4j-api + + + org.gcube.core + common-encryption + + + org.gcube.core + common-scope + + + org.gcube.core + common-smartgears-app + + + org.gcube.common + authorization-utils + [2.2.0, 3.0.0-SNAPSHOT) + + + org.gcube.information-system + information-system-model + + + org.gcube.resource-management + gcube-model + + + org.gcube.information-system + resource-registry-client + + + org.gcube.information-system + resource-registry-publisher + + + org.gcube.information-system + resource-registry-query-template-client + + + org.glassfish.jersey.containers + jersey-container-servlet + + + javax.ws.rs + javax.ws.rs-api + + + + + javax.xml.ws + jaxws-api + provided + + + org.projectlombok + lombok + provided + + + + + org.gcube.common + gxHTTP + + + org.gcube.common + keycloak-client + + + + org.gcube.core + common-smartgears + + + + com.webcohesion.enunciate + enunciate-core-annotations + ${enunciate.version} + provided + + + com.webcohesion.enunciate + enunciate-rt-util + ${enunciate.version} + provided + + + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + + + + junit + junit + 4.11 + test + + + ch.qos.logback + logback-classic + test + + + + + + + kr.motd.maven + sphinx-maven-plugin + 2.10.0 + + ${project.build.directory}/${project.artifactId}-${project.version}/docs + html + ${basedir}/docs + ${basedir}/docs + + + + process-resources + + generate + + + + + + + + com.webcohesion.enunciate + enunciate-maven-plugin + ${enunciate.version} + + + assemble + + assemble + + + + + + + org.apache.maven.plugins + maven-resources-plugin + + + copy-enunciate-docs + process-resources + + copy-resources + + + target + + + ${project.build.directory}/${project.artifactId}-${project.version}/api-docs + ${project.build.directory}/api-docs + true + + + + + + + + + + org.apache.maven.plugins + maven-war-plugin + + true + + + + + \ No newline at end of file diff --git a/src/main/java/org/gcube/resourcemanagement/ResourceInitializer.java b/src/main/java/org/gcube/resourcemanagement/ResourceInitializer.java new file mode 100644 index 0000000..dc17c1b --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/ResourceInitializer.java @@ -0,0 +1,22 @@ +package org.gcube.resourcemanagement; + +import javax.ws.rs.ApplicationPath; + +import org.gcube.resourcemanagement.rest.BaseREST; +import org.gcube.resourcemanagement.rest.administration.Configuration; +import org.gcube.smartgears.annotations.ManagedBy; +import org.glassfish.jersey.server.ResourceConfig; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@ApplicationPath("/") +@ManagedBy(ResourceManagerInitializator.class) +public class ResourceInitializer extends ResourceConfig { + + public ResourceInitializer() { + packages(BaseREST.class.getPackage().toString()); + packages(Configuration.class.getPackage().toString()); + } + +} diff --git a/src/main/java/org/gcube/resourcemanagement/ResourceManagerInitializator.java b/src/main/java/org/gcube/resourcemanagement/ResourceManagerInitializator.java new file mode 100644 index 0000000..5a5d311 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/ResourceManagerInitializator.java @@ -0,0 +1,92 @@ +package org.gcube.resourcemanagement; + +import java.io.IOException; + +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.resourcemanagement.rest.RequestFilter; +import org.gcube.smartgears.ApplicationManager; +import org.gcube.smartgears.ContextProvider; +import org.gcube.smartgears.context.application.ApplicationContext; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +public class ResourceManagerInitializator implements ApplicationManager { + + /** + * Logger + */ + private static Logger logger = LoggerFactory.getLogger(ResourceManagerInitializator.class); + + public static boolean initialised; + + /** + * {@inheritDoc} + * The method discover the plugins available on classpath and their own + * supported capabilities and publish a ServiceEndpoint with the + * discovered information. + * Furthermore create/connect to DB + */ + @Override + public synchronized void onInit() { + RequestFilter requestFilter = new RequestFilter(); + try { + requestFilter.filter(null); + } catch (IOException e) { + throw new RuntimeException(e); + } + + String context = SecretManagerProvider.instance.get().getContext(); + + logger.trace( + "\n-------------------------------------------------------\n" + + "Resource Manager is Starting on context {}\n" + + "-------------------------------------------------------", + context); + + ApplicationContext applicationContext = ContextProvider.get(); + String rrEServiceID = applicationContext.id(); + + + logger.trace( + "\n-------------------------------------------------------\n" + + "Resource Manager Started Successfully on context {}\n" + + "-------------------------------------------------------", + context); + + } + + /** + * {@inheritDoc} + * This function is invoked before the service will stop and unpublish the + * resource from the IS to maintain the infrastructure integrity. + * Furthermore close the connection to DB. + */ + @Override + public synchronized void onShutdown(){ + RequestFilter requestFilter = new RequestFilter(); + try { + requestFilter.filter(null); + } catch (IOException e) { + throw new RuntimeException(e); + } + + String context = SecretManagerProvider.instance.get().getContext(); + + logger.trace( + "\n-------------------------------------------------------\n" + + "Resource Manager is Stopping on context {}\n" + + "-------------------------------------------------------", + context); + + + + logger.trace( + "\n-------------------------------------------------------\n" + + "Resource Manager Stopped Successfully on context {}\n" + + "-------------------------------------------------------", + context); + } +} diff --git a/src/main/java/org/gcube/resourcemanagement/rest/BaseREST.java b/src/main/java/org/gcube/resourcemanagement/rest/BaseREST.java new file mode 100644 index 0000000..20b8956 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/BaseREST.java @@ -0,0 +1,58 @@ +package org.gcube.resourcemanagement.rest; + +import javax.ws.rs.core.Context; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.UriInfo; + +import org.gcube.common.authorization.library.provider.CalledMethodProvider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.webcohesion.enunciate.metadata.rs.RequestHeader; +import com.webcohesion.enunciate.metadata.rs.RequestHeaders; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@RequestHeaders ({ + @RequestHeader( name = "Authorization", description = "Bearer token, see https://dev.d4science.org/how-to-access-resources") +}) +public class BaseREST { + + private final Logger logger = LoggerFactory.getLogger(this.getClass()); + + public static final String APPLICATION_JSON_CHARSET_UTF_8 = "application/json;charset=UTF-8"; + public static final String APPLICATION_JSON_API = "application/vnd.api+json"; + public static final String COUNT_KEY = "count"; + public static final String PURGE_QUERY_PARAMETER = "purge"; + + @Context + protected HttpHeaders httpHeaders; + + @Context + protected UriInfo uriInfo; + + protected static final String LOCATION_HEADER = "Location"; + + protected void setCalledMethod(String method) { + CalledMethodProvider.instance.set(method); + logger.info("{}", uriInfo.getAbsolutePath()); + } + + protected ResponseBuilder addLocation(ResponseBuilder responseBuilder, String id) { + return responseBuilder.header(LOCATION_HEADER, + String.format("%s/%s", uriInfo.getAbsolutePath().toString(), id)); + } + + protected String createCountJson(int count) { + StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append("{\""); + stringBuilder.append(COUNT_KEY); + stringBuilder.append("\":"); + stringBuilder.append(count); + stringBuilder.append("}"); + return stringBuilder.toString(); + } + +} diff --git a/src/main/java/org/gcube/resourcemanagement/rest/RequestFilter.java b/src/main/java/org/gcube/resourcemanagement/rest/RequestFilter.java new file mode 100644 index 0000000..f39e716 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/RequestFilter.java @@ -0,0 +1,60 @@ +package org.gcube.resourcemanagement.rest; + +import java.io.IOException; + +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.container.PreMatching; +import javax.ws.rs.ext.Provider; + +import org.gcube.common.authorization.library.provider.AccessTokenProvider; +import org.gcube.common.authorization.library.provider.SecurityTokenProvider; +import org.gcube.common.authorization.utils.manager.SecretManager; +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.common.authorization.utils.secret.GCubeSecret; +import org.gcube.common.authorization.utils.secret.JWTSecret; +import org.gcube.common.authorization.utils.secret.Secret; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@Provider +@PreMatching +public class RequestFilter implements ContainerRequestFilter, ContainerResponseFilter { + + private final static Logger logger = LoggerFactory.getLogger(RequestFilter.class); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + logger.trace("PreMatching RequestFilter"); + + SecretManagerProvider.instance.remove(); + SecretManager secretManager = new SecretManager(); + + String token = AccessTokenProvider.instance.get(); + if(token!=null) { + Secret secret = new JWTSecret(token); + secretManager.addSecret(secret); + } + + token = SecurityTokenProvider.instance.get(); + if(token!=null) { + Secret secret = new GCubeSecret(token); + secretManager.addSecret(secret); + } + + SecretManagerProvider.instance.set(secretManager); + } + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) + throws IOException { + logger.trace("ResponseFilter"); + SecretManagerProvider.instance.remove(); + } + +} diff --git a/src/main/java/org/gcube/resourcemanagement/rest/ResourceManagerExceptionMapper.java b/src/main/java/org/gcube/resourcemanagement/rest/ResourceManagerExceptionMapper.java new file mode 100644 index 0000000..5845d04 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/ResourceManagerExceptionMapper.java @@ -0,0 +1,38 @@ +package org.gcube.resourcemanagement.rest; + +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 javax.ws.rs.ext.ExceptionMapper; +import javax.ws.rs.ext.Provider; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@Provider +public class ResourceManagerExceptionMapper implements ExceptionMapper { + + @Override + public Response toResponse(Exception exception) { + + Status status = Status.INTERNAL_SERVER_ERROR; + String exceptionMessage = exception.getMessage(); + try { + if(exception.getCause() != null) { + exceptionMessage = exception.getCause().getMessage(); + } + } catch(Exception e) { + exceptionMessage = exception.getMessage(); + } + MediaType mediaType = MediaType.TEXT_PLAIN_TYPE; + + if(WebApplicationException.class.isAssignableFrom(exception.getClass())) { + Response gotResponse = ((WebApplicationException) exception).getResponse(); + status = Status.fromStatusCode(gotResponse.getStatusInfo().getStatusCode()); + } + + return Response.status(status).entity(exceptionMessage).type(mediaType).build(); + } + +} diff --git a/src/main/java/org/gcube/resourcemanagement/rest/administration/Configuration.java b/src/main/java/org/gcube/resourcemanagement/rest/administration/Configuration.java new file mode 100644 index 0000000..4d418a0 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/administration/Configuration.java @@ -0,0 +1,340 @@ +package org.gcube.resourcemanagement.rest.administration; + +import javax.ws.rs.BadRequestException; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.GET; +import javax.ws.rs.InternalServerErrorException; +//import javax.ws.rs.NotAuthorizedException; +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.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; +import javax.xml.ws.WebServiceException; + +import org.gcube.common.authorization.utils.manager.SecretManagerProvider; +import org.gcube.resourcemanagement.rest.BaseREST; +import org.gcube.resourcemanagement.rest.annotation.PATCH; +import org.gcube.resourcemanagement.rest.annotation.PURGE; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.webcohesion.enunciate.metadata.rs.ResourceGroup; +import com.webcohesion.enunciate.metadata.rs.ResourceLabel; +import com.webcohesion.enunciate.metadata.rs.ResponseCode; +import com.webcohesion.enunciate.metadata.rs.StatusCodes; +import com.webcohesion.enunciate.metadata.swagger.OperationId; + +/** + * The catalogue configuration for the context of the request + * (i.e. the context where the token has been generated). + * + * Only Catalogue-Managers are able to invoke non-safe methods. + * + * @author Luca Frosini (ISTI - CNR) + */ +@Path(Configuration.CONFIGURATIONS) +@ResourceGroup("Administration APIs") +@ResourceLabel("Configuration APIs") +public class Configuration extends BaseREST { + + private static Logger logger = LoggerFactory.getLogger(Configuration.class); + + public static final String CONFIGURATIONS = "configurations"; + public static final String CURRENT_CONTEXT_PATH_PARAMETER = "CURRENT_CONTEXT"; + public static final String CONTEXT_FULLNAME_PARAMETER = "CONTEXT_FULLNAME_PARAMETER"; + + protected String checkContext(String context) throws WebServiceException { + if(context==null || context.compareTo("")==0) { + throw new BadRequestException("Please provide a valid context as path parameter"); + } + + String c = SecretManagerProvider.instance.get().getContext(); + if(context.compareTo(Configuration.CURRENT_CONTEXT_PATH_PARAMETER)==0) { + return c; + } + + if(context.compareTo(c)!=0) { + throw new BadRequestException("Context provided as path parameter (i.e. " + context + ") does not match with token request context (i.e. " + c + ")"); + } + + return c; + } + + private String createOrUpdate() throws WebServiceException { + return null; + } + + /** + * This API allows to create the catalogue configuration for the + * context of the request (i.e. the context where the token has been generated) + * using the json provided as request body.
+ */ + @POST + @Consumes(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) + @Produces(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) + @StatusCodes ({ + @ResponseCode(code = 201, condition = "Resource Manager configuration successfully created."), + @ResponseCode(code = 401, condition = "Only Manager can create the configuration."), + @ResponseCode(code = 500, condition = "Error while persisting the configuration."), + }) + public Response create(String json) throws WebServiceException { + try { + String ret = createOrUpdate(); + ResponseBuilder responseBuilder = Response.status(Status.CREATED); + if(ret!=null) { + responseBuilder.entity(ret).type(BaseREST.APPLICATION_JSON_CHARSET_UTF_8); + } + return responseBuilder.build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + /** + * This API allows to read the RR configuration for the + * current context (i.e. the context where the token has been generated).
+ * + * + */ + @GET + @Path("/{" + CONTEXT_FULLNAME_PARAMETER + "}") + @Produces(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) +// @AuthorizationControl(allowedRoles={Role.CATALOGUE_EDITOR, Role.CATALOGUE_ADMIN, Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class) + @StatusCodes ({ + @ResponseCode(code = 200, condition = "Resource Manager configuration successfully read."), + @ResponseCode(code = 401, condition = "Only User with role Manager above can read the configuration."), + @ResponseCode(code = 500, condition = "Error while reading catalogue configuration."), + }) + /** + * @param context + * @return + * @throws WebServiceException + */ + public Response read(@PathParam(CONTEXT_FULLNAME_PARAMETER) String context) throws WebServiceException { + try { + checkContext(context); + return read(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + public Response read() throws WebServiceException { + try { + String configuration = ""; + logger.debug("Configuration in context {} is {}", "", configuration); + ResponseBuilder responseBuilder = Response.status(Status.OK); + if(configuration!=null) { + responseBuilder.entity(configuration).type(BaseREST.APPLICATION_JSON_CHARSET_UTF_8); + } + return responseBuilder.build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + /** + * This API allows to create/update the catalogue configuration for the + * context of the request (i.e. the context where the token has been generated) + * using the json provided as request body.
+ */ + @PUT + @Path("/{" + CONTEXT_FULLNAME_PARAMETER + "}") + @Consumes(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) + @Produces(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) +// @AuthorizationControl(allowedRoles={Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class) + @StatusCodes ({ + @ResponseCode(code = 200, condition = "Catalogue configuration successfully created/updated."), + @ResponseCode(code = 401, condition = "Only Catalogue-Managers can create/update catalogue configuration."), + @ResponseCode(code = 500, condition = "Error while creating/updating catalogue configuration."), + }) + @OperationId("Create or Update") + public String createOrUpdate(@PathParam(CONTEXT_FULLNAME_PARAMETER) String context, String json) throws WebServiceException { + try { + return null; + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + public Response update(String json) throws WebServiceException { + try { + String configuration = ""; + logger.debug("Configuration in context {} has been updated to {}", "", configuration); + ResponseBuilder responseBuilder = Response.status(Status.OK); + if(configuration!=null) { + responseBuilder.entity(configuration).type(BaseREST.APPLICATION_JSON_CHARSET_UTF_8); + } + return responseBuilder.build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + /** + * This API allows to patch the catalogue configuration for the + * context of the request (i.e. the context where the token has been generated) + * using the json provided as request body.
+ */ + @PATCH + @Path("/{" + CONTEXT_FULLNAME_PARAMETER + "}") + @Consumes(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) + @Produces(BaseREST.APPLICATION_JSON_CHARSET_UTF_8) +// @AuthorizationControl(allowedRoles={Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class) + @StatusCodes ({ + @ResponseCode(code = 200, condition = "Catalogue configuration successfully updated."), + @ResponseCode(code = 401, condition = "Only Catalogue-Managers can update catalogue configuration."), + @ResponseCode(code = 500, condition = "Error while updating catalogue configuration."), + }) + public Response patch(@PathParam(CONTEXT_FULLNAME_PARAMETER) String context, String json) throws WebServiceException { + try { + checkContext(context); + return patch(json); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + public Response patch(String json) throws WebServiceException { + try { + String ret = ""; + logger.debug("Configuration in context {} has been patched to {}", "", ret); + ResponseBuilder responseBuilder = Response.status(Status.OK); + if(ret!=null) { + responseBuilder.entity(ret).type(BaseREST.APPLICATION_JSON_CHARSET_UTF_8); + } + return responseBuilder.build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + /** + * It removes from the cache the configuration for the + * context of the request (i.e. the context where the token has been generated).
+ * + * This API forces the service to read again from the Information System (IS) + * the resource manager configuration for the context of the request.
+ * + * If the user specifies the purge query parameter this API + * remove the configuration from the IS. Please note that this implies that + * the resource manager is no more configured for the context of the request. + * + * + * @param context context must contains the context of the request + * (i.e. the context where the token has been generated) + * or the placeholder CURRENT_CONTEXT.
+ * Please note that the context must be URL encoded, + * e.g. /gcube/devsec/devVRE -> %2Fgcube%2Fdevsec%2FdevVRE + * @param purge indicates to the service to remove the configuration from the IS + * @throws WebServiceException + * + * @pathExample /configurations/CURRENT_CONTEXT + */ + @DELETE + @Path("/{" + CONTEXT_FULLNAME_PARAMETER + "}") +// @AuthorizationControl(allowedRoles={Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class) + @StatusCodes ({ + @ResponseCode(code = 200, condition = "Catalogue configuration successfully deleted."), + @ResponseCode(code = 401, condition = "Only Catalogue-Managers can delete catalogue configuration."), + @ResponseCode(code = 500, condition = "Error while deleting catalogue configuration."), + }) + public Response delete(@PathParam(CONTEXT_FULLNAME_PARAMETER) String context, + @QueryParam(BaseREST.PURGE_QUERY_PARAMETER) @DefaultValue("false") Boolean purge) throws WebServiceException { + try { + checkContext(context); + if(purge) { + return purge(); + }else { + return delete(); + } + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + // Remove the configuration from cache and force reload + public Response delete() throws WebServiceException { + try { + + return Response.status(Status.NO_CONTENT).build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + /** + * It removes remove the configuration from the IS for the + * context of the request (i.e. the context where the token has been generated).
+ * + * Please note that this implies that + * the resource manager is no more configured for the context of the request. + * + * @param context context must contains the context of the request + * (i.e. the context where the token has been generated) + * or the placeholder CURRENT_CONTEXT.
+ * Please note that the context must be URL encoded, + * e.g. /gcube/devsec/devVRE -> %2Fgcube%2Fdevsec%2FdevVRE + * @throws WebServiceException + * + * @pathExample /configurations/CURRENT_CONTEXT + * + */ + @PURGE + @Path("/{" + CONTEXT_FULLNAME_PARAMETER + "}") +// @AuthorizationControl(allowedRoles={Role.CATALOGUE_MANAGER}, exception=NotAuthorizedException.class) + @StatusCodes ({ + @ResponseCode(code = 200, condition = "Catalogue configuration successfully deleted."), + @ResponseCode(code = 401, condition = "Only Catalogue-Managers can delete catalogue configuration."), + @ResponseCode(code = 500, condition = "Error while deleting catalogue configuration."), + }) + public Response purge(@PathParam(CONTEXT_FULLNAME_PARAMETER) String context) throws WebServiceException { + try { + checkContext(context); + return purge(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + + // Remove the configuration from cache and from IS + public Response purge() throws WebServiceException { + try { + + return Response.status(Status.NO_CONTENT).build(); + }catch (WebApplicationException e) { + throw e; + }catch (Exception e) { + throw new InternalServerErrorException(e); + } + } + +} diff --git a/src/main/java/org/gcube/resourcemanagement/rest/annotation/PATCH.java b/src/main/java/org/gcube/resourcemanagement/rest/annotation/PATCH.java new file mode 100644 index 0000000..0d05b65 --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/annotation/PATCH.java @@ -0,0 +1,17 @@ +package org.gcube.resourcemanagement.rest.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("PATCH") +public @interface PATCH { +} \ No newline at end of file diff --git a/src/main/java/org/gcube/resourcemanagement/rest/annotation/PURGE.java b/src/main/java/org/gcube/resourcemanagement/rest/annotation/PURGE.java new file mode 100644 index 0000000..f4dd7de --- /dev/null +++ b/src/main/java/org/gcube/resourcemanagement/rest/annotation/PURGE.java @@ -0,0 +1,17 @@ +package org.gcube.resourcemanagement.rest.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.ws.rs.HttpMethod; + +/** + * @author Luca Frosini (ISTI - CNR) + */ +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@HttpMethod("PURGE") +public @interface PURGE { +} \ No newline at end of file