diff --git a/README.md b/README.md index 345af156..40c2dc02 100644 --- a/README.md +++ b/README.md @@ -4,28 +4,42 @@ ## Installation -### Docker +### Docker You must install [Docker](https://www.docker.com/) and [docker-compose](https://docs.docker.com/compose/install/). Clone the repository -```bash +```console $ git clone https://github.com/KnowledgeCaptureAndDiscovery/wings.git ``` Deploy the container with the following command: -```bash +```console $ docker-compose up -d ``` - Open the browser [http://localhost:8080/wings-portal](http://localhost:8080/wings-portal) to access the Wings portal. +To stop the container, run the following command: + +```bash +$ docker-compose down +``` + +#### Users + +The default user is `admin` and the password is `4dm1n!23`. You can change the password in the `./wings-docker/config/tomcat/tomcat-users.xml` and rebuild the container. + +``` +$ docker-compose build +$ docker-compose up -d +``` -Go to [README Docker](wings-docker/) for additional instructions on running the Docker image. +#### Configuration +Please follow the instructions in [README Configuration](docs/configuration.md) to configure the Wings project. #### Images diff --git a/docker-compose.yml b/docker-compose.yml index 8d22bc5c..6973163d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -11,6 +11,7 @@ services: - wings_data:/opt/wings - /var/run/docker.sock:/var/run/docker.sock - ./portal.properties:/etc/wings/portal.properties + ports: - 8080:8080 volumes: diff --git a/docs/configuration.md b/docs/configuration.md new file mode 100644 index 00000000..d48b2dbf --- /dev/null +++ b/docs/configuration.md @@ -0,0 +1,84 @@ +# Wings configuration documentation + +The wings configuration file is located at `/etc/wings/portal.properties`. It contains the following sections: + +- **main**: modify main properties +- **storage**: modify the paths where the data and database is stored +- **ontology**: reference to the WINGS ontology +- **execution**: available engines to run the workflow +- **publisher**: describes how the wings system shares data, execution, and provenance. + +Be sure to modify the configuration file carefully, as changes may affect the functionality of the Wings system. + +To inspect the configuration file, open a browser and go to [http://localhost:8080/wings-portal/config](http://localhost:8080/wings-portal/config). The sensitive information is hidden. + +### Main + +The **main** section of the configuration file allows you to modify the main properties of the Wings system. + +| Name | Description | Default | +| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | +| server | The URL of the Wings instance is used to generate the accessible URI for resources. For example, if the value is set to the default, the component library of the domain CaesarCypher and user admin will be available at http://localhost:8080/wings-portal/export/users/admin/CaesarCypher/components/library.owl. | Obtained by HTTP request. For example, http://localhost:8080 | +| graphviz | Path where the graphviz software is installed | /usr/bin/dot | +| light-reasoner | Enable or disable validation in the planning of workflow | false | + +### Storage + +The **storage** section of the configuration file allows you to specify the location of the data and database directories. Make sure to set the paths to directories with sufficient storage space and appropriate permissions for the following properties: + +| name | description | default value | +| ------------- | -------------------------------------------------- | -------------------- | +| storage.local | Directory where the data and components are stored | $HOME/.wings/storage | +| storage.local | RDF store database (Apache JENA) | $HOME/.wings/TDB | +| storage.local | Directory where the log files are stored | $HOME/.wings/logs | + +### Ontology + +The following text describes the ontology section of the Wings configuration file. The properties within this section should not be modified unless you are an advanced user with knowledge of the WINGS ontology + +The ontology section of the configuration file specifies the location and URIs of the WINGS ontology files. The following properties defin + +| Name | Description | Default Value | +| ------------------ | ----------------------------------------------------- | ----------------------------------------------------- | +| ontology.component | Location and URI of the WINGS ontology component ont | http://www.wings-workflows.org/ontology/component.owl | +| ontology.data | Location and URI of the WINGS ontology data file | http://www.wings-workflows.org/ontology/data.owl | +| ontology.execution | Location and URI of the WINGS ontology execution file | http://www.wings-workflows.org/ontology/execution.owl | +| ontology.workflow | Location and URI of the WINGS ontology workflow file | http://www.wings-workflows.org/ontology/workflow.owl | + +Again, these properties should not be modified unless you are an advanced user with knowledge of the WINGS ontology. + +### Execution and engine + +The "Execution" section lists the available engines for running your workflows. + +| Name | Description | +| -------------- | ---------------------------------------------------------- | +| name | A short name to describe the engine | +| implementation | Java path where the implementation is | +| type | Modify if the engine is used in the planning, step or both | + +WINGS supports the following engines: + +1. `local` runs the workflow as a UNIX process. +2. `distributed` runs the workflows using round robin, connecting to the server using the SSH protocol. + +By default, the local engine is activated. + +```json +execution = + { + engine = + { + name = Local; + implementation = edu.isi.wings.execution.engine.api.impl.local.LocalExecutionEngine; + type = BOTH; + } + + engine = + { + name = Distributed; + implementation = edu.isi.wings.execution.engine.api.impl.distributed.DistributedExecutionEngine; + type = BOTH; + } + } +``` diff --git a/portal/src/main/java/edu/isi/wings/portal/classes/config/ExecutionConfig.java b/portal/src/main/java/edu/isi/wings/portal/classes/config/ExecutionConfig.java index 5739a04a..e93af233 100644 --- a/portal/src/main/java/edu/isi/wings/portal/classes/config/ExecutionConfig.java +++ b/portal/src/main/java/edu/isi/wings/portal/classes/config/ExecutionConfig.java @@ -16,30 +16,22 @@ public class ExecutionConfig { public ExecutionConfig(PropertyListConfiguration serverConfig) { this.engines = new HashMap(); - List engineNodes = serverConfig.configurationsAt( - "execution.engine" - ); - for (HierarchicalConfiguration engineNode : engineNodes) { - ExecutionEngineConfig engine = this.getExeEngine(engineNode); - this.engines.put(engine.getName(), engine); - } - } - - public ExecutionConfig() { - this.engines = new HashMap(); - ExecutionEngineConfig defaultLocal = new ExecutionEngineConfig( - "Local", - LocalExecutionEngine.class.getCanonicalName(), - ExecutionEngineConfig.Type.BOTH - ); - ExecutionEngineConfig defaultDistrubited = new ExecutionEngineConfig( - "Distributed", - DistributedExecutionEngine.class.getCanonicalName(), - ExecutionEngineConfig.Type.BOTH - ); + if (serverConfig.containsKey("execution.engine")) { + List engineNodes = + serverConfig.configurationsAt("execution.engine"); + for (HierarchicalConfiguration engineNode : engineNodes) { + ExecutionEngineConfig engine = this.getExeEngine(engineNode); + this.engines.put(engine.getName(), engine); + } + } else { + ExecutionEngineConfig defaultLocal = new ExecutionEngineConfig( + "Local", + LocalExecutionEngine.class.getCanonicalName(), + ExecutionEngineConfig.Type.BOTH + ); - this.engines.put(defaultLocal.getName(), defaultLocal); - this.engines.put(defaultDistrubited.getName(), defaultDistrubited); + this.engines.put(defaultLocal.getName(), defaultLocal); + } } @SuppressWarnings("rawtypes") diff --git a/portal/src/main/java/edu/isi/wings/portal/classes/config/MainConfig.java b/portal/src/main/java/edu/isi/wings/portal/classes/config/MainConfig.java index 6332b64b..5ac2d739 100644 --- a/portal/src/main/java/edu/isi/wings/portal/classes/config/MainConfig.java +++ b/portal/src/main/java/edu/isi/wings/portal/classes/config/MainConfig.java @@ -15,32 +15,36 @@ public class MainConfig { public static final String USERS_RELATIVE_DIR = "users"; public static final String EXPORT_SERVLET_PATH = "/export"; - public String dotFile; + public String dotFile = "/usr/bin/dot"; public String serverUrl; - public boolean hasMetaWorkflows; - public String clients; + public boolean hasMetaWorkflows = false; + public String clients = null; public String contextRootPath; public String exportCommunityUrl; public String communityPath; - public MainConfig(MainConfig source) { - this.dotFile = source.getDotFile(); - this.serverUrl = source.getServerUrl(); - this.hasMetaWorkflows = source.isHasMetaWorkflows(); - this.clients = source.getClients(); - this.contextRootPath = source.getContextRootPath(); - this.exportCommunityUrl = source.getExportCommunityUrl(); - this.communityPath = source.getCommunityPath(); - } - public MainConfig( PropertyListConfiguration serverConfig, HttpServletRequest request ) { - this.serverUrl = serverConfig.getString(MAIN_SERVER_KEY); - this.dotFile = serverConfig.getString(MAIN_GRAPHVIZ_KEY); - this.clients = serverConfig.getString(MAIN_CLIENTS_KEY); this.contextRootPath = request.getContextPath(); + if (serverConfig.containsKey(MAIN_GRAPHVIZ_KEY)) { + this.dotFile = serverConfig.getString(MAIN_GRAPHVIZ_KEY); + } + if (serverConfig.containsKey(MAIN_SERVER_KEY)) { + this.serverUrl = serverConfig.getString(MAIN_SERVER_KEY); + } else { + this.serverUrl = + request.getScheme() + + "://" + + request.getServerName() + + ":" + + request.getServerPort(); + } + if (serverConfig.containsKey(MAIN_CLIENTS_KEY)) { + this.clients = serverConfig.getString(MAIN_CLIENTS_KEY); + } + if ( serverConfig.containsKey(MAIN_METAWORKFLOWS_KEY) ) this.hasMetaWorkflows = serverConfig.getBoolean(MAIN_METAWORKFLOWS_KEY); @@ -58,26 +62,6 @@ public MainConfig( StorageConfig.COMMUNITY_RELATIVE_DIR; } - public MainConfig(String defaultServer, HttpServletRequest request) { - this.serverUrl = defaultServer; - File loc1 = new File("/usr/bin/dot"); - File loc2 = new File("/usr/local/bin/dot"); - dotFile = loc2.exists() ? loc2.getAbsolutePath() : loc1.getAbsolutePath(); - this.contextRootPath = request.getContextPath(); - this.exportCommunityUrl = - this.serverUrl + - contextRootPath + - EXPORT_SERVLET_PATH + - "/" + - StorageConfig.COMMUNITY_RELATIVE_DIR; - this.communityPath = - contextRootPath + - "/" + - USERS_RELATIVE_DIR + - "/" + - StorageConfig.COMMUNITY_RELATIVE_DIR; - } - public static String getMainLightReasonerKey() { return MAIN_LIGHT_REASONER_KEY; } diff --git a/portal/src/main/java/edu/isi/wings/portal/classes/config/OntologyConfig.java b/portal/src/main/java/edu/isi/wings/portal/classes/config/OntologyConfig.java index 839d1bae..ac7bfc7a 100644 --- a/portal/src/main/java/edu/isi/wings/portal/classes/config/OntologyConfig.java +++ b/portal/src/main/java/edu/isi/wings/portal/classes/config/OntologyConfig.java @@ -37,8 +37,6 @@ public OntologyConfig(PropertyListConfiguration serverConfig) { } } - public OntologyConfig() {} - public String getComponentOntologyUrl() { return componentOntologyUrl; } diff --git a/portal/src/main/java/edu/isi/wings/portal/classes/config/PortalConfig.java b/portal/src/main/java/edu/isi/wings/portal/classes/config/PortalConfig.java index 745eeadd..ca267dac 100644 --- a/portal/src/main/java/edu/isi/wings/portal/classes/config/PortalConfig.java +++ b/portal/src/main/java/edu/isi/wings/portal/classes/config/PortalConfig.java @@ -32,10 +32,13 @@ public PropertyListConfiguration getPortalConfiguration( ) { ServletContext app = request.getSession().getServletContext(); this.portalConfigurationFile = obtainConfigPath(app, request); - if (this.portalConfigurationFile == null) createDefaultConfigurationFile( - request - ); - checkIfFileExists(this.portalConfigurationFile); + try { + checkIfFileExists(portalConfigurationFile); + } catch (Exception e) { + throw new RuntimeException( + "Could not find config file: " + portalConfigurationFile + ); + } return loadConfigurationOnProps(); } @@ -85,76 +88,6 @@ private void getPlannerConfiguration(PropertyListConfiguration serverConfig) { this.plannerConfig = new PlannerConfig(serverConfig); } - private void createDefaultConfigurationFile(HttpServletRequest request) { - String configFileName = "portal.properties"; - String configDirectory = createDefaultConfigurationDirectory(); - this.portalConfigurationFile = - configDirectory + File.separator + configFileName; - File cfile = new File(this.portalConfigurationFile); - File configDir = cfile.getParentFile(); - StorageConfig.createStorageDirectory(configDir.getAbsolutePath()); - if (request != null) createDefaultPortalConfig(request); - } - - private String createDefaultConfigurationDirectory() { - String defaultDirectory = ".wings"; - String home = System.getProperty("user.home"); - if (home != null && !home.equals("")) { - return home + File.separator + defaultDirectory; - } - return "/etc/wings/portal.properties"; - } - - private void createDefaultPortalConfig(HttpServletRequest request) { - String server = - request.getScheme() + - "://" + - request.getServerName() + - ":" + - request.getServerPort(); - - PropertyListConfiguration config = new PropertyListConfiguration(); - StorageConfig storageConfig = new StorageConfig(config); - OntologyConfig ontologyDefaultConfig = new OntologyConfig(); - MainConfig mainDefaultConfig = new MainConfig(server, request); - ExecutionConfig executionConfig = new ExecutionConfig(); - - config.addProperty(MainConfig.MAIN_SERVER_KEY, server); - config.addProperty(MainConfig.MAIN_GRAPHVIZ_KEY, mainDefaultConfig.dotFile); - config.addProperty( - StorageConfig.STORAGE_LOCAL, - storageConfig.storageDirectory - ); - config.addProperty(StorageConfig.STORAGE_TDB, storageConfig.tdbDirectory); - config.addProperty( - OntologyConfig.ONTOLOGY_COMPONENT_KEY, - ontologyDefaultConfig.componentOntologyUrl - ); - config.addProperty( - OntologyConfig.ONTOLOGY_DATA_KEY, - ontologyDefaultConfig.dataOntologyUrl - ); - config.addProperty( - OntologyConfig.ONTOLOGY_EXECUTION_KEY, - ontologyDefaultConfig.executionOntologyUrl - ); - config.addProperty( - OntologyConfig.ONTOLOGY_RESOURCE_KEY, - ontologyDefaultConfig.resourceOntologyUrl - ); - config.addProperty( - OntologyConfig.ONTOLOGY_WORKFLOW_KEY, - ontologyDefaultConfig.workflowOntologyUrl - ); - executionConfig.addDefaultEngineConfig(config); - - try { - config.save(this.portalConfigurationFile); - } catch (Exception e) { - e.printStackTrace(); - } - } - private void getEngineNodeConfiguration( PropertyListConfiguration serverConfig ) { diff --git a/portal/src/main/java/edu/isi/wings/portal/classes/config/StorageConfig.java b/portal/src/main/java/edu/isi/wings/portal/classes/config/StorageConfig.java index a608d44b..fc683297 100644 --- a/portal/src/main/java/edu/isi/wings/portal/classes/config/StorageConfig.java +++ b/portal/src/main/java/edu/isi/wings/portal/classes/config/StorageConfig.java @@ -27,7 +27,7 @@ public StorageConfig(PropertyListConfiguration serverConfig) { } this.logsDirectory = this.storageDirectory + File.separator + LOGS_DIRECTORY; - this.logsDirectory = this.storageDirectory + File.separator + TDB_DIRECTORY; + this.tdbDirectory = this.storageDirectory + File.separator + TDB_DIRECTORY; this.communityDirectory = this.storageDirectory + File.separator + COMMUNITY_RELATIVE_DIR; diff --git a/wings-docker/config/default/portal.properties b/wings-docker/config/default/portal.properties index dace1762..2c63c085 100644 --- a/wings-docker/config/default/portal.properties +++ b/wings-docker/config/default/portal.properties @@ -1,52 +1,2 @@ { - storage = - { - local = /opt/wings/storage/default; - tdb = /opt/wings/storage/default/TDB; - } - - server = http://localhost:8080; - graphviz = /usr/bin/dot; - light-reasoner = false; - ontology = - { - data = http://www.wings-workflows.org/ontology/data.owl; - component = http://www.wings-workflows.org/ontology/component.owl; - workflow = http://www.wings-workflows.org/ontology/workflow.owl; - execution = http://www.wings-workflows.org/ontology/execution.owl; - } - - execution = - { - engine = - { - name = Local; - implementation = edu.isi.wings.execution.engine.api.impl.local.LocalExecutionEngine; - type = BOTH; - } - - engine = - { - name = Distributed; - implementation = edu.isi.wings.execution.engine.api.impl.distributed.DistributedExecutionEngine; - type = BOTH; - } - } - - publisher = - { - url = "https://publisher.mint.isi.edu"; - name = "exportTest" - upload-server = - { - url = "https://publisher.mint.isi.edu"; - username = "user"; - password = "password"; - } - triple-store = { - publish = http://ontosoft.isi.edu:3030/provenance/data; - query = http://ontosoft.isi.edu:3030/provenance/sparql; - domains-directory = /opt/wings/storage/default; - } - } } diff --git a/wings-docker/config/default/wings-portal.xml b/wings-docker/config/default/wings-portal.xml index 272e5c07..b27949b0 100644 --- a/wings-docker/config/default/wings-portal.xml +++ b/wings-docker/config/default/wings-portal.xml @@ -2,4 +2,4 @@ - + \ No newline at end of file