Skip to Content.
Sympa Menu

idok-commit - [idok-commit] idok commit r231 - branches/rest/java/ch/idok/service/server/admin/rest

idok-commit AT lists.psi.ch

Subject: Commit emails of the iDok project

List archive

[idok-commit] idok commit r231 - branches/rest/java/ch/idok/service/server/admin/rest


Chronological Thread 
  • From: "AFS account Roman Geus" <geus AT savannah.psi.ch>
  • To: idok-commit AT lists.psi.ch
  • Subject: [idok-commit] idok commit r231 - branches/rest/java/ch/idok/service/server/admin/rest
  • Date: Tue, 23 Sep 2008 17:54:00 +0200
  • List-archive: <https://lists.web.psi.ch/pipermail/idok-commit/>
  • List-id: Commit emails of the iDok project <idok-commit.lists.psi.ch>

Author: geus
Date: Tue Sep 23 17:54:00 2008
New Revision: 231

Log:
Added more functionality to admin ReST interface, updated to match latest
JAX-RS draft

Modified:

branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java

Modified:
branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
==============================================================================
---
branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
(original)
+++
branches/rest/java/ch/idok/service/server/admin/rest/RestAdminServiceResource.java
Tue Sep 23 17:54:00 2008
@@ -1,21 +1,26 @@
package ch.idok.service.server.admin.rest;

import java.io.File;
+import java.io.FileOutputStream;
import java.io.FileReader;
+import java.io.InputStream;
import java.security.AccessControlException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.security.auth.Subject;
+import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
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.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.SecurityContext;
import javax.ws.rs.core.UriInfo;
+import javax.ws.rs.core.Response.Status;

import ch.idok.common.errorhandling.DmsException;
import ch.idok.common.errorhandling.ErrorType;
@@ -26,6 +31,7 @@
import ch.idok.service.server.admin.PermissionAdapter;
import ch.idok.service.server.admin.PermissionAdapterFactory;
import ch.idok.service.server.rest.IdokNegotiateFilter;
+import ch.idok.service.server.rest.RestExceptionResponse;
import ch.idok.service.server.rest.RestServer;

@Path("admin")
@@ -60,7 +66,7 @@
@Produces("text/html")
public Response getRoot() {
try {
- logger.entering(this.getClass().getName(), "project");
+ logger.entering(this.getClass().getName(), "getRoot");

DmsCredentials cred = null;
if (securityContext.getUserPrincipal() != null) {
@@ -91,7 +97,7 @@
return Response.ok().entity(sb).build();
} catch (Exception e) {
logger.log(Level.FINER, "Error in REST call", e);
- return Response.serverError().entity("DmsException: " +
e).build();
+ return RestExceptionResponse.generateXHTML(e);
}

}
@@ -102,10 +108,10 @@
public Response putRoot() throws Exception {
// TODO make configurable
final String masterAdminName = "geus";
-
+
try {
logger.entering(this.getClass().getName(), "putRoot");
-
+
Subject subject = aa(null);
String authUser = AuthUtil.getStrippedName(AuthUtil
.getUserPrincipal(subject));
@@ -115,7 +121,7 @@
+ " does not have sufficient permissions for
this operation");
throw new DmsException(
ErrorType.AUTHENTICATION,
- null,
+ null,
"Permission denied",
authUser
+ " does not have sufficient permissions for
this operation");
@@ -125,7 +131,7 @@
return Response.ok().entity("success").build();
} catch (Throwable e) {
logger.log(Level.WARNING, e.getMessage(), e);
- return Response.serverError().entity("DmsException: " +
e).build();
+ return RestExceptionResponse.generateXHTML(e);
}
}

@@ -134,7 +140,7 @@
@Produces("text/html")
public Response getProject(@PathParam("project") String project) {
try {
- logger.entering(this.getClass().getName(), "project", project);
+ logger.entering(this.getClass().getName(), "getProject",
project);

Admin.validateName(project);
Subject subject = aa(new DmsPermission(project, "read"));
@@ -146,8 +152,8 @@
project));

// List of repositories
- sb.append(String.format("<p>Repositories of project %s:</p><ul>",
- project));
+ sb.append(String.format(
+ "<p>Repositories of project <i>%s</i>:</p><ul>",
project));
// Loop over all repositories within the project
for (String repository : Admin.listRepositories(project)) {
try {
@@ -176,19 +182,52 @@
return Response.ok().entity(sb).build();
} catch (Exception e) {
logger.log(Level.FINER, "Error in REST call", e);
-
- return Response.serverError().entity("DmsException: " +
e).build();
+ return RestExceptionResponse.generateXHTML(e);
}

}

+ /**
+ * Create a new iDok project
+ *
+ * @param project
+ * project name
+ * @return response
+ */
+ @PUT
+ @Path("{project}")
+ @Produces("text/html")
+ public Response putProject(@PathParam("project") String project,
+ @QueryParam("quota") String quotaString) {
+ try {
+ logger.entering(this.getClass().getName(), "putProject",
+ new Object[] { project, quotaString });
+ int quota = Integer.parseInt(quotaString);
+
+ Admin.validateName(project);
+ Subject subject = aa(new DmsPermission("<admin>", "admin"));
+ if (Admin.projectExists(project))
+ return RestExceptionResponse
+ .clientErrorXHTML("Project with the given name
already exists");
+ Admin.createProject(AuthUtil.getUserPrincipal(subject).getName(),
+ project, quota);
+ return Response.created(uriInfo.getRequestUri()).build();
+ } catch (NumberFormatException e) {
+ return RestExceptionResponse
+ .clientErrorXHTML("Could not parse the quota parameter");
+ } catch (Throwable e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+ return RestExceptionResponse.generateXHTML(e);
+ }
+ }
+
@GET
- @Path(value="{project}/{repository}", limited=true)
+ @Path(value = "{project}/{repository}")
@Produces("text/html")
public Response getRepository(@PathParam("project") String project,
@PathParam("repository") String repository) {
try {
- logger.entering(this.getClass().getName(), "repository",
+ logger.entering(this.getClass().getName(), "getRepository",
new Object[] { project, repository });

Admin.validateName(project);
@@ -224,19 +263,54 @@
return Response.ok().entity(sb).build();
} catch (Exception e) {
logger.log(Level.FINER, "Error in REST call", e);
-
- return Response.serverError().entity("DmsException: " +
e).build();
+ return RestExceptionResponse.generateXHTML(e);
}

}

+ /**
+ * Create a new iDok project
+ *
+ * @param project
+ * project name
+ * @return response
+ */
+ @PUT
+ @Path("{project}/{repository}")
+ @Produces("text/html")
+ public Response putRepository(@PathParam("project") String project,
+ @PathParam("repository") String repository) {
+ try {
+ logger.entering(this.getClass().getName(), "putProject",
+ new Object[] { project, repository });
+
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ Subject subject = aa(new DmsPermission(project, "admin"));
+ if (Admin.repositoryExists(project, repository))
+ return RestExceptionResponse
+ .clientErrorXHTML("Project with the given name
already exists");
+ Admin.createRepository(
+ AuthUtil.getUserPrincipal(subject).getName(), project,
+ repository);
+
+ // FIXME: not efficient
+ Admin.forceAuthzUpdate();
+
+ return Response.created(uriInfo.getRequestUri()).build();
+ } catch (Throwable e) {
+ logger.log(Level.FINER, "Error in REST call", e);
+ return RestExceptionResponse.generateXHTML(e);
+ }
+ }
+
@GET
@Path("{project}/{repository}/schema")
@Produces("text/html")
public Response getSchemas(@PathParam("project") String project,
@PathParam("repository") String repository) {
try {
- logger.entering(this.getClass().getName(), "schemas");
+ logger.entering(this.getClass().getName(), "getSchemas");

Admin.validateName(project);
Admin.validateName(repository);
@@ -265,8 +339,7 @@
return Response.ok().entity(sb).build();
} catch (Exception e) {
logger.log(Level.FINER, "Error in REST call", e);
-
- return Response.serverError().entity("DmsException: " +
e).build();
+ return RestExceptionResponse.generateXHTML(e);
}

}
@@ -278,10 +351,12 @@
@PathParam("repository") String repository,
@PathParam("schema") String schema) {
try {
- logger.entering(this.getClass().getName(), "schema");
+ logger.entering(this.getClass().getName(), "getSchema",
+ new Object[] { project, repository, schema });

Admin.validateName(project);
Admin.validateName(repository);
+ Admin.validateName(schema);
aa(new DmsPermission(project + "/" + repository, "read"));

StringBuilder sb = new StringBuilder();
@@ -293,6 +368,13 @@
"<head><title>Schema %s for repository
%s/%s</title></head>",
schema, project, repository));

+ sb
+ .append(String
+ .format(
+ "<p>Schema <i>%s</i> of <a
class=\"repository\" href=\"%s\">repository %s/%s</a></p>",
+ schema, getRepositoryURI(project,
+ repository), project,
repository));
+
// Schema file content
sb.append("<p>Schema content:</p>");
sb.append("<pre>");
@@ -300,7 +382,7 @@
FileReader is = new FileReader(schemaFile);
int ch = is.read();
while (ch != -1) {
- sb.append(ch);
+ sb.append(Character.valueOf((char) ch));
ch = is.read();
}
sb.append("</pre>");
@@ -309,8 +391,80 @@
return Response.ok().entity(sb).build();
} catch (Exception e) {
logger.log(Level.FINER, "Error in REST call", e);
+ return RestExceptionResponse.generateXHTML(e);
+ }
+
+ }
+
+ @PUT
+ @Path("{project}/{repository}/schema/{schema}")
+ @Produces("text/html")
+ public Response putSchema(@PathParam("project") String project,
+ @PathParam("repository") String repository,
+ @PathParam("schema") String schema, InputStream is) {
+ final boolean exists;
+ final int bufferSize = 4096;
+
+ byte[] buf = new byte[bufferSize];
+
+ logger.entering(this.getClass().getName(), "putSchema", new Object[]
{
+ project, repository, schema, is });
+
+ try {
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ Admin.validateName(schema);
+ aa(new DmsPermission(project + "/" + repository, "admin"));
+ File file = Admin.getSchemaFile(project, repository, schema);
+ if (file.exists())
+ exists = true;
+ else
+ exists = false;
+ FileOutputStream os = new FileOutputStream(file);
+ int bytesRead;
+ while ((bytesRead = is.read(buf)) != -1) {
+ os.write(buf, 0, bytesRead);
+ }
+ os.close();
+ if (exists)
+ return Response.created(uriInfo.getRequestUri()).entity("ok")
+ .build();
+ else
+ return Response.ok("ok").build();
+ } catch (Throwable e) {
+ logger.log(Level.FINER, e.getMessage(), e);
+ return RestExceptionResponse.generateXHTML(e);
+ }
+
+ }
+
+ @DELETE
+ @Path("{project}/{repository}/schema/{schema}")
+ @Produces("text/html")
+ public Response deleteSchema(@PathParam("project") String project,
+ @PathParam("repository") String repository,
+ @PathParam("schema") String schema) {
+ logger.entering(this.getClass().getName(), "deleteSchema",
+ new Object[] { project, repository, schema });

- return Response.serverError().entity("DmsException: " +
e).build();
+ try {
+ Admin.validateName(project);
+ Admin.validateName(repository);
+ Admin.validateName(schema);
+ aa(new DmsPermission(project + "/" + repository, "admin"));
+ File file = Admin.getSchemaFile(project, repository, schema);
+ if (!file.exists())
+ return Response.status(Status.NOT_FOUND).build();
+ else {
+ boolean done = file.delete();
+ if (done)
+ return Response.ok("ok").build();
+ else
+ return Response.serverError().build();
+ }
+ } catch (Throwable e) {
+ logger.log(Level.FINER, e.getMessage(), e);
+ return RestExceptionResponse.generateXHTML(e);
}

}
@@ -319,7 +473,8 @@
* Authenticate and authorize
*
* Checks if the request was successfully authenticated (e.g. by
- * NegotiateFilter) and if the authenticated user has the requested
permission.
+ * NegotiateFilter) and if the authenticated user has the requested
+ * permission.
*
* @param permission
* Permission to check for
@@ -357,7 +512,8 @@
}

private String getRepositoryURI(String project, String repository) {
- return project + "/" + repository;
+ return
uriInfo.getBaseUriBuilder().path(this.getClass()).path(project)
+ .path(repository).toString();
}

}



  • [idok-commit] idok commit r231 - branches/rest/java/ch/idok/service/server/admin/rest, AFS account Roman Geus, 09/23/2008

Archive powered by MHonArc 2.6.19.

Top of Page