blob: b83d88fd7e08a98e844693f6f498e2974e918c3b [file] [log] [blame]
/*
* Copyright (C) 2011 The University of Manchester
*
* See the file "LICENSE" for license terms.
*/
package org.taverna.server.master.admin;
import static java.util.Arrays.asList;
import static java.util.UUID.randomUUID;
import static javax.ws.rs.core.Response.created;
import static javax.ws.rs.core.Response.noContent;
import static javax.ws.rs.core.Response.Status.NOT_FOUND;
import static org.taverna.server.master.common.Roles.ADMIN;
import static org.taverna.server.master.common.Uri.secure;
import static org.taverna.server.master.utils.RestUtils.opt;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Required;
import org.taverna.server.master.api.ManagementModel;
import org.taverna.server.master.exceptions.GeneralFailureException;
import org.taverna.server.master.factories.ConfigurableRunFactory;
import org.taverna.server.master.identity.User;
import org.taverna.server.master.identity.UserStoreAPI;
import org.taverna.server.master.usage.UsageRecordRecorder;
import org.taverna.server.master.utils.InvocationCounter;
import org.taverna.server.master.worker.RunDBSupport;
import org.taverna.server.master.worker.WorkerModel;
/**
* The administration interface to Taverna Server.
*
* @author Donal Fellows
*/
public class AdminBean implements Admin {
@Required
public void setState(ManagementModel state) {
this.state = state;
}
@Required
public void setCounter(InvocationCounter counter) {
this.counter = counter;
}
@Required
public void setRunDB(RunDBSupport runDB) {
this.runDB = runDB;
}
@Required
public void setFactory(ConfigurableRunFactory factory) {
this.factory = factory;
}
@Required
public void setUsageRecords(UsageRecordRecorder usageRecords) {
this.usageRecords = usageRecords;
}
@Required
public void setUserStore(UserStoreAPI userStore) {
this.userStore = userStore;
}
@Required
public void setLocalWorkerModel(WorkerModel worker) {
localWorker = worker;
}
public void setAdminHtmlFile(String filename) {
this.adminHtmlFile = filename;
}
public void setResourceRoot(String root) {
this.resourceRoot = root;
}
protected byte[] getResource(String name) throws IOException {
if (AdminBean.class.getResource(name) == null)
throw new FileNotFoundException(name);
return IOUtils.toByteArray(AdminBean.class.getResourceAsStream(name));
}
private ManagementModel state;
private InvocationCounter counter;
private RunDBSupport runDB;
private ConfigurableRunFactory factory;
private UsageRecordRecorder usageRecords;
private UserStoreAPI userStore;
private WorkerModel localWorker;
private String adminHtmlFile = "/admin.html";
private String resourceRoot = "/static/";
@RolesAllowed(ADMIN)
@Override
public Response getUserInterface() throws IOException {
return Response.ok(getResource(adminHtmlFile), "text/html").build();
}
@Override
@RolesAllowed(ADMIN)
public Response getStaticResource(String file) throws IOException {
if (file.matches("^[-_.a-zA-Z0-9]+$")) {
String type = "application/octet-stream";
if (file.endsWith(".html"))
type = "text/html";
else if (file.endsWith(".js"))
type = "text/javascript";
else if (file.endsWith(".jpg"))
type = "image/jpeg";
else if (file.endsWith(".gif"))
type = "image/gif";
else if (file.endsWith(".png"))
type = "image/png";
else if (file.endsWith(".svg"))
type = "image/svg+xml";
else if (file.endsWith(".css"))
type = "text/css";
try {
return Response.ok(getResource(resourceRoot + file), type)
.build();
} catch (IOException e) {
// ignore; we just treat as 404
}
}
return Response.status(NOT_FOUND).entity("no such resource").build();
}
@RolesAllowed(ADMIN)
@Override
public AdminDescription getDescription(UriInfo ui) {
return new AdminDescription(ui);
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRoot() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public boolean getAllowNew() {
return state.getAllowNewWorkflowRuns();
}
@RolesAllowed(ADMIN)
@Override
public boolean setAllowNew(boolean newValue) {
state.setAllowNewWorkflowRuns(newValue);
return state.getAllowNewWorkflowRuns();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsAllowNew() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public boolean getLogWorkflows() {
return state.getLogIncomingWorkflows();
}
@RolesAllowed(ADMIN)
@Override
public boolean setLogWorkflows(boolean newValue) {
state.setLogIncomingWorkflows(newValue);
return state.getLogIncomingWorkflows();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsLogWorkflows() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public boolean getLogFaults() {
return state.getLogOutgoingExceptions();
}
@RolesAllowed(ADMIN)
@Override
public boolean setLogFaults(boolean newValue) {
state.setLogOutgoingExceptions(newValue);
return state.getLogOutgoingExceptions();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsLogFaults() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getURFile() {
return state.getUsageRecordLogFile();
}
@RolesAllowed(ADMIN)
@Override
public String setURFile(String newValue) {
state.setUsageRecordLogFile(newValue);
return state.getUsageRecordLogFile();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsURFile() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int invokeCount() {
return counter.getCount();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public Response optionsInvokationCount() {
return opt();
}
@RolesAllowed(ADMIN)
@Override
public int runCount() {
return runDB.countRuns();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRunCount() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getRegistryHost() {
return factory.getRegistryHost();
}
@RolesAllowed(ADMIN)
@Override
public String setRegistryHost(String newValue) {
factory.setRegistryHost(newValue);
return factory.getRegistryHost();
}
@Override
public Response optionsRegistryHost() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getRegistryPort() {
return factory.getRegistryPort();
}
@RolesAllowed(ADMIN)
@Override
public int setRegistryPort(int newValue) {
factory.setRegistryPort(newValue);
return factory.getRegistryPort();
}
@Override
public Response optionsRegistryPort() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getRegistryJar() {
return factory.getRmiRegistryJar();
}
@RolesAllowed(ADMIN)
@Override
public String setRegistryJar(String registryJar) {
factory.setRmiRegistryJar(registryJar);
return factory.getRmiRegistryJar();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRegistryJar() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getRunLimit() {
return factory.getMaxRuns();
}
@RolesAllowed(ADMIN)
@Override
public int setRunLimit(int newValue) {
factory.setMaxRuns(newValue);
return factory.getMaxRuns();
}
@Override
public Response optionsRunLimit() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getDefaultLifetime() {
return factory.getDefaultLifetime();
}
@RolesAllowed(ADMIN)
@Override
public int setDefaultLifetime(int newValue) {
factory.setDefaultLifetime(newValue);
return factory.getDefaultLifetime();
}
@Override
public Response optionsDefaultLifetime() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public StringList currentRuns() {
StringList result = new StringList();
result.string = runDB.listRunNames();
return result;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsCurrentRuns() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getJavaBinary() {
return factory.getJavaBinary();
}
@RolesAllowed(ADMIN)
@Override
public String setJavaBinary(String newValue) {
factory.setJavaBinary(newValue);
return factory.getJavaBinary();
}
@Override
public Response optionsJavaBinary() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public StringList getExtraArguments() {
String[] xargs = factory.getExtraArguments();
StringList result = new StringList();
result.string = asList(xargs == null ? new String[0] : xargs);
return result;
}
@RolesAllowed(ADMIN)
@Override
public StringList setExtraArguments(StringList newValue) {
if (newValue == null || newValue.string == null)
factory.setExtraArguments(new String[0]);
else
factory.setExtraArguments(newValue.string
.toArray(new String[newValue.string.size()]));
StringList result = new StringList();
result.string = asList(factory.getExtraArguments());
return result;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsExtraArguments() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getServerWorkerJar() {
return factory.getServerWorkerJar();
}
@RolesAllowed(ADMIN)
@Override
public String setServerWorkerJar(String newValue) {
factory.setServerWorkerJar(newValue);
return factory.getServerWorkerJar();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsServerWorkerJar() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getExecuteWorkflowScript() {
return factory.getExecuteWorkflowScript();
}
@RolesAllowed(ADMIN)
@Override
public String setExecuteWorkflowScript(String newValue) {
factory.setExecuteWorkflowScript(newValue);
return factory.getExecuteWorkflowScript();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsExecuteWorkflowScript() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getRegistrationWaitSeconds() {
return factory.getWaitSeconds();
}
@RolesAllowed(ADMIN)
@Override
public int setRegistrationWaitSeconds(int newValue) {
factory.setWaitSeconds(newValue);
return factory.getWaitSeconds();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRegistrationWaitSeconds() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getRegistrationPollMillis() {
return factory.getSleepTime();
}
@RolesAllowed(ADMIN)
@Override
public int setRegistrationPollMillis(int newValue) {
factory.setSleepTime(newValue);
return factory.getSleepTime();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRegistrationPollMillis() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getRunasPasswordFile() {
return factory.getPasswordFile();
}
@RolesAllowed(ADMIN)
@Override
public String setRunasPasswordFile(String newValue) {
factory.setPasswordFile(newValue);
return factory.getPasswordFile();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsRunasPasswordFile() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getServerForkerJar() {
return factory.getServerForkerJar();
}
@RolesAllowed(ADMIN)
@Override
public String setServerForkerJar(String newValue) {
factory.setServerForkerJar(newValue);
return factory.getServerForkerJar();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsServerForkerJar() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int startupTime() {
return factory.getLastStartupCheckCount();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsStartupTime() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public Integer lastExitCode() {
return factory.getLastExitCode();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsLastExitCode() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public StringList factoryProcessMapping() {
StringList result = new StringList();
result.string = asList(factory.getFactoryProcessMapping());
return result;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsFactoryProcessMapping() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public URList usageRecords() {
URList result = new URList();
result.usageRecord = usageRecords.getUsageRecords();
return result;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsUsageRecords() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public UserList users(UriInfo ui) {
UserList ul = new UserList();
UriBuilder ub = secure(ui).path("{id}");
for (String user : userStore.getUserNames())
ul.user.add(ub.build(user));
return ul;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsUsers() {
return opt("POST");
}
@RolesAllowed(ADMIN)
@Override
public UserDesc user(String username) {
UserDesc desc = new UserDesc();
User u = userStore.getUser(username);
desc.username = u.getUsername();
desc.localUserId = u.getLocalUsername();
desc.admin = u.isAdmin();
desc.enabled = u.isEnabled();
return desc;
}
@RolesAllowed(ADMIN)
@Override
public Response optionsUser(String username) {
return opt("PUT", "DELETE");
}
@RolesAllowed(ADMIN)
@Override
public Response useradd(UserDesc userdesc, UriInfo ui) {
if (userdesc.username == null)
throw new IllegalArgumentException("no user name supplied");
if (userdesc.password == null)
userdesc.password = randomUUID().toString();
userStore.addUser(userdesc.username, userdesc.password, false);
if (userdesc.localUserId != null)
userStore.setUserLocalUser(userdesc.username, userdesc.localUserId);
if (userdesc.admin != null && userdesc.admin)
userStore.setUserAdmin(userdesc.username, true);
if (userdesc.enabled != null && userdesc.enabled)
userStore.setUserEnabled(userdesc.username, true);
return created(secure(ui).path("{id}").build(userdesc.username))
.build();
}
@RolesAllowed(ADMIN)
@Override
public UserDesc userset(String username, UserDesc userdesc) {
if (userdesc.password != null)
userStore.setUserPassword(username, userdesc.password);
if (userdesc.localUserId != null)
userStore.setUserLocalUser(username, userdesc.localUserId);
if (userdesc.admin != null)
userStore.setUserAdmin(username, userdesc.admin);
if (userdesc.enabled != null)
userStore.setUserEnabled(username, userdesc.enabled);
userdesc = null; // Stop reuse!
UserDesc desc = new UserDesc();
User u = userStore.getUser(username);
desc.username = u.getUsername();
desc.localUserId = u.getLocalUsername();
desc.admin = u.isAdmin();
desc.enabled = u.isEnabled();
return desc;
}
@RolesAllowed(ADMIN)
@Override
public Response userdel(String username) {
userStore.deleteUser(username);
return noContent().build();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int operatingCount() {
try {
return factory.getOperatingCount();
} catch (Exception e) {
throw new GeneralFailureException(e);
}
}
@RolesAllowed(ADMIN)
@Override
public Response optionsOperatingCount() {
return opt();
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public int getOperatingLimit() {
return factory.getOperatingLimit();
}
@RolesAllowed(ADMIN)
@Override
public int setOperatingLimit(int operatingLimit) {
factory.setOperatingLimit(operatingLimit);
return factory.getOperatingLimit();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsOperatingLimit() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public StringList getPermittedWorkflowURIs() {
StringList sl = new StringList();
List<URI> uris = localWorker.getPermittedWorkflowURIs();
if (uris != null)
for (URI uri : uris)
sl.string.add(uri.toString());
return sl;
}
private static final URI myExp = URI.create("http://www.myexperment.org/");
@RolesAllowed(ADMIN)
@Override
public StringList setPermittedWorkflowURIs(StringList permitted) {
List<URI> uris = new ArrayList<>();
for (String uri : permitted.string)
try {
uris.add(myExp.resolve(uri));
} catch (Exception e) {
// Ignore
}
localWorker.setPermittedWorkflowURIs(uris);
return getPermittedWorkflowURIs();
}
@RolesAllowed(ADMIN)
@Override
public Response optionsPermittedWorkflowURIs() {
return opt("PUT");
}
// /////////////////////////////////////////////////////
@RolesAllowed(ADMIN)
@Override
public String getGenerateProvenance() {
return Boolean.toString(localWorker.getGenerateProvenance());
}
@RolesAllowed(ADMIN)
@Override
public String setGenerateProvenance(String newValue) {
boolean b = Boolean.parseBoolean(newValue);
localWorker.setGenerateProvenance(b);
return Boolean.toString(localWorker.getGenerateProvenance());
}
@RolesAllowed(ADMIN)
@Override
public Response optionsGenerateProvenance() {
return opt("PUT");
}
}