Skip to content

Commit

Permalink
update deps and test for reading some witsml entities (#17)
Browse files Browse the repository at this point in the history
* update deps and test for reading some witsml entities

* new verification taking car of WITSML sub element (AbstractObject inside Other AbstractObject like ChannelSet in Log) + new REST API for epc/xml validation and correction

* README

* readme

* bugfix in creation object selection with package name in web interface
  • Loading branch information
valentin-gauthier-geosiris authored Dec 22, 2023
1 parent a3f7846 commit a86aaff
Show file tree
Hide file tree
Showing 15 changed files with 610 additions and 371 deletions.
31 changes: 31 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ The WebStudio is a web application that allows to manipulate energyml file (such
- 3D visu :
- *ColorInformation* in a *GraphicalInformationSet* can be used if it references an **HSV color** in a *DiscreteColorMap*

- 1.0.14:
- REST API :
- A REST API has been added to be able to validate/fix EPC/xml files.
- Bugfix :
- Sometimes export the EPC file was failing from the interface. It was due to specific entities that were not supported for export.
- Witsml/Prodml objects (like **Log**) can contain as *sub-objects* other *AbstractObject*. They are now detected during validation/auto-correction.

## License

This project is licensed under the Apache 2.0 License - see the `LICENSE` file for details
Expand Down Expand Up @@ -184,3 +191,27 @@ Change the **docker/server-production.xml** to have a connector like this:
</SSLHostConfig>
</Connector>
```

## REST API

The WebStudio provides a simple REST API to validate and correct EPC/xml files.

### Validation : "/EnergymlValidation"

A post request on the endpoint "/EnergymlValidation" with files inside "form-data" will return a json file containing information about the correctness of your xml/epc files.

The messages help you with a dotted notation for each error. Example : *".ChanelSet.O.Channel.1"* means the 2nd Channel xml element in the 1st sub xml element "ChannelSet".

Example with postman :
![POSTMAN-validation-request](doc/image/REST/postman-energyml-validation.png)

### Correction : "/EnergymlFix"

A post request on the endpoint "/EnergymlFix" with files inside "form-data" will return an EPC file containing all of your xml files (even taken from an input EPC file), and also a log file that describes the modifications done to correct your entities.

For now the only correction done is on DOR information. If an object refers to an other one with its UUID, the *Title* and the *QualifiedType*/*ContentType* are verified and eventually fixed.

**Export version:** The resulting EPC can follow the old file naming convention "/[ENERGYML_TYPE]\_[UUID].xml" but also the new one : "/[PACKAGE][PACKAGE\_VERSION]/[ENERGYML\_TYPE]_[UUID].xml". The new version is obtainable by sending a parameter called "version" with the value **EXPANDED** (uppercase).

Example with postman :
![POSTMAN-correction-request](doc/image/REST/postman-energyml-fix.png)
Binary file added doc/image/REST/postman-energyml-fix.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/image/REST/postman-energyml-validation.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 28 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<groupId>com.geosiris</groupId>
<artifactId>webstudio</artifactId>
<name>${project.groupId}:${project.artifactId}</name>
<version>1.0.12</version>
<version>1.0.14</version>
<organization>
<name>Geosiris</name>
<url>http://www.geosiris.com</url>
Expand Down Expand Up @@ -63,7 +63,7 @@
<dependency>
<groupId>com.geosiris</groupId>
<artifactId>energyml-utils</artifactId>
<version>1.0.7</version>
<version>1.0.9</version>
</dependency>
<dependency>
<groupId>com.geosiris</groupId>
Expand Down Expand Up @@ -135,6 +135,19 @@
<artifactId>jol-core</artifactId>
<version>0.10</version>
</dependency>
<!-- Tests -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build/>
<profiles>
Expand Down Expand Up @@ -178,5 +191,18 @@
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<build>
<plugins>
<!-- Tests -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.2</version>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
14 changes: 10 additions & 4 deletions src/main/java/com/geosiris/webstudio/model/WorkspaceContent.java
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,16 @@ public void setAdditionalInformation(Map<String, Object> additionalInformation)
}

public void putAll(WorkspaceContent rf) {
this.notReadObjects.addAll(rf.notReadObjects);
this.readObjects.putAll(rf.readObjects);
this.additionalInformation.putAll(rf.additionalInformation);
this.parsedRels.putAll(rf.parsedRels);
if(rf != null){
if(rf.notReadObjects != null)
this.notReadObjects.addAll(rf.notReadObjects);
if(rf.readObjects != null)
this.readObjects.putAll(rf.readObjects);
if(rf.additionalInformation != null)
this.additionalInformation.putAll(rf.additionalInformation);
if(rf.parsedRels != null)
this.parsedRels.putAll(rf.parsedRels);
}
}

public Map<String, Relationships> getParsedRels() {
Expand Down
88 changes: 7 additions & 81 deletions src/main/java/com/geosiris/webstudio/servlet/ExportEPCFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,9 @@
*/
package com.geosiris.webstudio.servlet;

import com.geosiris.energyml.utils.EPCGenericManager;
import com.geosiris.energyml.utils.ExportVersion;
import com.geosiris.energyml.utils.Pair;
import com.geosiris.webstudio.model.WorkspaceContent;
import com.geosiris.webstudio.utils.HttpSender;
import com.geosiris.webstudio.utils.SessionUtility;
import jakarta.servlet.ServletContext;
import jakarta.servlet.ServletException;
Expand All @@ -30,16 +29,12 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
* Servlet implementation class ExportEPCFile
Expand Down Expand Up @@ -103,46 +98,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t
}
// FIN filtrage fichiers a exporter

try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
exportEPCFile(bos,
workspace,
exportVersion);
byte[] bos_bytes = bos.toByteArray();
request.setAttribute("response", "File exported");

request.setAttribute("response", "File exported");
// obtains ServletContext
ServletContext context = getServletContext();

// obtains ServletContext
ServletContext context = getServletContext();

// gets MIME type of the file
String mimeType = context.getMimeType(filePath);
if (mimeType == null) {
// set to binary type if MIME mapping not found
mimeType = "application/octet-stream";
}

response.setContentType(mimeType);
// response.setContentLength((int) downloadFile.length());
response.setContentLength(bos_bytes.length);

// forces download
String headerKey = "Content-Disposition";
String headerValue = String.format("attachment; filename=\"%s\"", filePath);
response.setHeader(headerKey, headerValue);

// obtains response's output stream
OutputStream outStream = response.getOutputStream();

for(int chunk=0; chunk<bos_bytes.length; chunk+= 4096){
outStream.write(bos_bytes, chunk, Math.min(4096, bos_bytes.length-chunk));
}

outStream.close();
} catch (Exception e) {
logger.error(e.getMessage(), e);
request.setAttribute("response", "Error occured while exporting file : \n" + e.getMessage() + " \n " + Arrays.toString(e.getStackTrace()));
}
// gets MIME type of the file
String mimeType = context.getMimeType(filePath);
HttpSender.writeEpcAsRequestResponse(response, workspace, filePath, exportVersion, mimeType);

String closeEpc = request.getParameter("close");
if (closeEpc != null && closeEpc.toLowerCase().compareTo("true") == 0) {
Expand All @@ -162,41 +125,4 @@ protected void doPost(HttpServletRequest request, HttpServletResponse response)
doGet(request, response);
}

public static void exportEPCFile(OutputStream out,
WorkspaceContent workspace,
ExportVersion exportVersion){
logger.info("@exportEPCFile");
try {
try(ZipOutputStream epc = new ZipOutputStream(out)) {
for (Map.Entry<String, Object> kv : workspace.getReadObjects().entrySet()) {
ZipEntry ze_resqml = new ZipEntry(EPCGenericManager.genPathInEPC(kv.getValue(), exportVersion));
epc.putNextEntry(ze_resqml);
Editor.pkgManager.marshal(kv.getValue(), epc);
epc.closeEntry();
}
EPCGenericManager.exportRels(workspace.getReadObjects(), workspace.getParsedRels(), exportVersion, epc, "Geosiris Resqml WebStudio");

if (workspace.getNotReadObjects() != null) {
/// non resqml obj
for (Pair<String, byte[]> nonResqmlObj : workspace.getNotReadObjects()) {
ZipEntry ze_resqml = new ZipEntry(nonResqmlObj.l());
epc.putNextEntry(ze_resqml);
try {
byte[] fileContent = nonResqmlObj.r();
for(int chunk=0; chunk<fileContent.length; chunk += 4096){
epc.write(fileContent, chunk, Math.min(4096, fileContent.length-chunk));
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
logger.error("nonResqmlObj " + nonResqmlObj.l());
}
epc.closeEntry();
}
}
// epc.finish();
}
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
}
}
Loading

0 comments on commit a86aaff

Please sign in to comment.