Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 17 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ SBOLCanvas is a web application for creation and editing of genetic constructs u
## SynBioSuite Branch

This branch is specifically for SBOLCanvas as embedded in the [SynBioSuite app](https://github.com/MyersResearchGroup/SynBioSuite);
however, it can still function as a standalone application.
however, it can still function as a standalone application.

## Repository Structure

This is a monorepo containing an Angular app as a frontend (in the frontend directory)
and a Dockerized Java API (in the backend directory) that handles things like
and a Dockerized Java API (in the backend directory) that handles things like
conversion, communication with SynBioHub, etc.

This differs from the *final* branch, which Dockerizes the frontend and backend
together, and serves the Angular app from the backend.

The changes made were an optimization to allow the API to be deployed serverlessly
and the frontend to be deployed as a static web app served from CDNs.
and the frontend to be deployed as a static web app served from CDNs.

## Run Locally

Clone the project
Expand Down Expand Up @@ -62,6 +64,7 @@ Start the Angular development server
```bash
npm run dev
```

Or, if you plan to develop the frontend, use

```bash
Expand All @@ -75,11 +78,14 @@ Alternatively, you can build both the frontend and backend together on one Docke
```bash
docker build -t sbolcanvas .
```

and then

```bash
docker run --rm --name canvas --publish 4040:8080 sbolcanvas
```
A local instance will be available on http://localhost:4040/

A local instance will be available on <http://localhost:4040/>

If you plan to contribute to this repository, this is recommended before you open a Pull Request. GitHub Actions will use a similar process to check the Docker build and deployment.

Expand All @@ -92,6 +98,11 @@ cd SBOLCanvasBackend
mvn test
```

```bash
# when adding a new test class, run a clean build
mvn clean test
```

Frontend:

```bash
Expand All @@ -108,15 +119,14 @@ npm run build
```

The built output will be available in frontend/dist and can be deployed anywhere
a static web app can be deployed. Genetic Logic Lab's weapon of choice is
a static web app can be deployed. Genetic Logic Lab's weapon of choice is
[Azure Static Web Apps](https://azure.microsoft.com/en-us/products/app-service/static/).

To build the backend, from the backend directory, run

```bash
docker build -t sbolcanvas .
```

The resulting Docker image can be deployed anywhere you can run Docker containers.
Genetic Logic Lab uses [Azure Container Apps](https://azure.microsoft.com/en-us/products/container-apps/).


Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
public class CombinatorialInfo extends Info {

private String templateURI;
private String version;
private String strategy;
private String name;
private String description;
Expand All @@ -19,14 +18,6 @@ public void setTemplateURI(String templateURI) {
this.templateURI = templateURI;
}

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getStrategy() {
return strategy;
}
Expand Down Expand Up @@ -59,12 +50,4 @@ public void setVariableComponents(Hashtable<String, VariableComponentInfo> varia
this.variableComponents = variableComponents;
}

public String getFullURI() {
String fullURI = this.uriPrefix + '/' + this.displayID;
if (this.version != null && this.version.length() > 0) {
fullURI += '/' + this.version;
}
return fullURI;
}

}
27 changes: 18 additions & 9 deletions SBOLCanvasBackend/src/main/java/org/sbolcanvas/data/EventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,8 @@
public class EventInfo extends Info {

private Hashtable<String, Object> simulationData;

@Override
public String getFullURI() {
if (uriPrefix == null || displayID == null) {
throw new IllegalStateException(
"EventInfo has null uriPrefix or displayID (uriPrefix=" + uriPrefix + ", displayID=" + displayID + ")");
}
return uriPrefix + "/" + displayID;
}
private String name;
private String description;

public Hashtable<String, Object> getSimulationData() {
return simulationData;
Expand All @@ -23,4 +16,20 @@ public void setSimulationData(Hashtable<String, Object> simulationData) {
this.simulationData = simulationData;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public String getDescription() {
return description;
}

public void setDescription(String description) {
this.description = description;
}

}
17 changes: 0 additions & 17 deletions SBOLCanvasBackend/src/main/java/org/sbolcanvas/data/GlyphInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ public class GlyphInfo extends Info {
private String partRefine;
private String name;
private String description;
private String version;
private String sequence;
private String sequenceURI;
private CanvasAnnotation[] annotations;
Expand Down Expand Up @@ -75,14 +74,6 @@ public void setDescription(String description) {
this.description = description;
}

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getSequence() {
return this.sequence;
}
Expand Down Expand Up @@ -130,12 +121,4 @@ public Hashtable<String, Object> getSimulationData() {
public void setSimulationData(Hashtable<String, Object> simulationData) {
this.simulationData = simulationData;
}

public String getFullURI() {
String fullURI = this.uriPrefix + '/' + this.displayID;
if(this.version != null && this.version.length() > 0) {
fullURI += '/' + this.version;
}
return fullURI;
}
}
38 changes: 35 additions & 3 deletions SBOLCanvasBackend/src/main/java/org/sbolcanvas/data/Info.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@ public abstract class Info {

protected String uriPrefix;
protected String displayID;
protected String version;

public String getFullURI() {
if (uriPrefix == null || displayID == null) {
throw new IllegalStateException(
"Info has null uriPrefix or displayID (uriPrefix=" + uriPrefix + ", displayID=" + displayID + ")");
}
String fullURI = this.uriPrefix + '/' + this.displayID;
if (this.version != null && this.version.length() > 0) {
fullURI += '/' + this.version;
}
return fullURI;
}

abstract String getFullURI();

public String getUriPrefix() {
return uriPrefix;
}
Expand All @@ -22,5 +33,26 @@ public String getDisplayID() {
public void setDisplayID(String displayID) {
this.displayID = displayID;
}


public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getName() {
return null;
}

/** The human-facing label: the name when one is set, else the displayID. */
public String getDisplayName() {
String name = getName();
if (name != null && !name.trim().isEmpty()) {
return name;
}
return displayID;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ public class ModuleInfo extends Info {

private String name;
private String description;
private String version;

public String getName() {
return name;
Expand All @@ -22,20 +21,4 @@ public void setDescription(String description) {
this.description = description;
}

public String getVersion() {
return version;
}

public void setVersion(String version) {
this.version = version;
}

public String getFullURI() {
String fullURI = this.uriPrefix + '/' + this.displayID;
if(this.version != null && this.version.length() > 0) {
fullURI += '/' + this.version;
}
return fullURI;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,17 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
} catch (SBOLValidationException | IOException | SBOLConversionException | ParserConfigurationException
| TransformerException | SAXException | TransformerFactoryConfigurationError | URISyntaxException | SynBioHubException | javax.xml.stream.XMLStreamException e) {
ServletOutputStream outputStream = response.getOutputStream();
String message = e.getMessage() != null ? e.getMessage() : "Export failed";
String action = "/toMxGraph".equals(request.getPathInfo()) ? "Import" : "Export";
String message = e.getMessage() != null ? e.getMessage() : action + " failed";
InputStream inputStream = new ByteArrayInputStream(message.getBytes());
IOUtils.copy(inputStream, outputStream);

response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
e.printStackTrace();
} catch (RuntimeException e) {
// Catch unchecked exceptions from SBML export
String message = e.getMessage() != null ? e.getMessage() : "Export failed";
String action = "/toMxGraph".equals(request.getPathInfo()) ? "Import" : "Export";
String message = e.getMessage() != null ? e.getMessage() : action + " failed";
ServletOutputStream outputStream = response.getOutputStream();
InputStream inputStream = new ByteArrayInputStream(message.getBytes());
IOUtils.copy(inputStream, outputStream);
Expand Down
Loading
Loading