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
Binary file modified .DS_Store
Binary file not shown.
44 changes: 13 additions & 31 deletions .github/workflows/plugin-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ on:
jobs:
build:
runs-on: ${{ matrix.operating-system }}
environment:
name: ${{ github.ref_name }}
strategy:
matrix:
operating-system: [ubuntu-latest]
versions: [ { jdk: 17, mapping-service: v1.0.5 }, { jdk: 21, mapping-service: latest } ]
versions: [ { jdk: 17, mapping-service: v2.0.2 }, { jdk: 21, mapping-service: latest } ]

steps:
- name: Checkout repository
Expand All @@ -34,8 +32,9 @@ jobs:
JAR_VERSION=$(./mappingservice-plugin/gradlew printVersion -q -p ./mappingservice-plugin/)
JAR_VERSION=${JAR_VERSION##*$'\n'}
./mappingservice-plugin/gradlew clean jar -p ./mappingservice-plugin/
ls -ll ./mappingservice-plugin/build/libs/
echo "JAR_VERSION=${JAR_VERSION}"
mv -v ./mappingservice-plugin/build/libs/ApeHePlugin-$JAR_VERSION-plain.jar ./mappingservice-plugin/build/libs/ApeHeplugin.jar
mv -v ./mappingservice-plugin/build/libs/ApeHePlugin-$JAR_VERSION.jar ./mappingservice-plugin/build/libs/ApeHeplugin.jar
env:
VERSION_OVERRIDE_BY_BRANCH: ${{ steps.extract_branch.outputs.branch }}

Expand All @@ -47,13 +46,11 @@ jobs:

test:
runs-on: ${{ matrix.operating-system }}
environment:
name: ${{ github.ref_name }}
strategy:
fail-fast: false
matrix:
operating-system: [ubuntu-latest]
versions: [ { jdk: 17, mapping-service: v1.0.5 }, { jdk: 21, mapping-service: latest } ]
versions: [ { jdk: 17, mapping-service: v2.0.2 }, { jdk: 21, mapping-service: latest } ]
needs: build

steps:
Expand All @@ -73,7 +70,7 @@ jobs:

- name: Run Docker Container
run: |
docker run -d -p 8095:8095 -e PIP_BREAK_SYSTEM_PACKAGES=1 -v ./plugins/ApeHeplugin.jar:/spring/mapping-service/plugins/ApeHeplugin.jar --name mapping4docker ghcr.io/kit-data-manager/mapping-service:${{ matrix.versions.mapping-service }}
docker run -d -p 8095:8095 -e PIP_BREAK_SYSTEM_PACKAGES=1 -e SPRING_APPLICATION_JSON='{"mapping-service.executionTimeout":300}' -v ./plugins/ApeHeplugin.jar:/spring/mapping-service/plugins/ApeHeplugin.jar --name mapping4docker ghcr.io/kit-data-manager/mapping-service:${{ matrix.versions.mapping-service }}
echo "Waiting for mapping service to be healthy..."
while true; do
if ! docker ps | grep -q mapping4docker; then
Expand All @@ -84,35 +81,20 @@ jobs:
echo "Service is running."
break
fi
echo "Waiting..."
echo "Waiting for the service to be ready ..."
docker logs --tail 20 mapping4docker
sleep 5
done

- name: Install Hurl & Prepare JSON
run: |
curl -LO https://github.com/Orange-OpenSource/hurl/releases/download/6.0.0/hurl_6.0.0_amd64.deb
sudo dpkg -i hurl_6.0.0_amd64.deb
sudo apt install -y dos2unix

# Fetch mappingType dynamically
mappingType=$(curl -s http://localhost:8095/api/v1/mappingAdministration/types | jq -r '.[0].id')

echo "Using mappingType: $mappingType"

echo "{\"mappingId\":\"96\",\"mappingType\":\"$mappingType\",\"title\":\"apeHe from CI test\",\"description\":\"\",\"acl\":[]}" > record.json
echo '{"entry.title.value": "entry.title"}' > document.json

unix2dos -n ./mappingservice-plugin/integrationtests/basic.hurl ./mappingservice-plugin/integrationtests/basic_crlf.hurl

- name: Run Tests with Hurl
run: |
hurl --variable host=http://localhost:8095 --test ./mappingservice-plugin/integrationtests/basic_crlf.hurl --verbose --file-root .
curl --location --remote-name https://github.com/Orange-OpenSource/hurl/releases/download/6.0.0/hurl_6.0.0_amd64.deb
sudo dpkg -i hurl_6.0.0_amd64.deb
sudo apt install -y dos2unix
unix2dos -n ./mappingservice-plugin/integrationtests/basic.hurl ./mappingservice-plugin/integrationtests/basic_crlf.hurl
hurl --variable host=http://localhost:8095 --test ./mappingservice-plugin/integrationtests/basic_crlf.hurl --verbose --file-root .
env:
VERSION_OVERRIDE_BY_BRANCH: ${{ steps.extract_branch.outputs.branch }}

- name: Clean up temp files
run: rm -f record.json document.json


- name: Stop Docker Container
run: docker stop mapping4docker
run: docker stop mapping4docker
2 changes: 1 addition & 1 deletion CITATION.cff
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type: software
title: APE-HE mapper
abstract: APE-HE Mapper is a tool designed for mapping APE-HE (Advanced Photoelectric
Effect - High Energy) metadata to a uniform, schema-compliant json format.
version: v1.0.0
version: v1.1.0rc
keywords:
- APE-HE
- neXus
Expand Down
2 changes: 1 addition & 1 deletion codemeta.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
],
"name": "APE-HE mapper",
"description": "APE-HE Mapper is a tool designed for mapping APE-HE (Advanced Photoelectric Effect - High Energy) metadata to a uniform, schema-compliant json format.",
"version": "v1.0.0",
"version": "v1.1.0rc",
"keywords": [
"APE-HE",
"neXus",
Expand Down
32 changes: 20 additions & 12 deletions mappingservice-plugin/build.gradle
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import org.tomlj.Toml
buildscript {
// Buildscript repositories
repositories {
mavenLocal()
mavenCentral()
}

dependencies {
classpath("org.tomlj:tomlj:1.1.1")
}
}

plugins {
id 'io.spring.dependency-management' version "1.1.7"
id 'org.springframework.boot' version "3.4.4"
id 'java'
}

group 'edu.kit.datamanager'
import org.tomlj.Toml

repositories {
mavenLocal()
mavenCentral()
}

dependencies {
implementation 'org.springframework:spring-core:6.2.5'
implementation 'org.slf4j:slf4j-api:2.0.17'
implementation files("src/main/lib/mapping-service-plain.jar")
implementation 'edu.kit.datamanager:mapping-plugin-core:2.0.0'
}

if (System.getenv('VERSION_OVERRIDE_BY_BRANCH')) {
Expand All @@ -32,22 +38,24 @@ tasks.register('printVersion') {
println project.version
}

group 'edu.kit.datamanager'

//Task for creating a resource file with the version info
tasks.register("generateVersionProps", WriteProperties) { t ->
def generatedResourcesDir = project.layout.buildDirectory.dir(["resources", "main"].join(File.separator))
def outputFile = generatedResourcesDir.map { it.file("apeHepluginversion.properties") }
def outputFile = generatedResourcesDir.map { it.file("apehe_nxs2json.properties") }

t.destinationFile = outputFile.get().asFile
t.property("version", project.version)
}

resolveMainClassName.dependsOn("generateVersionProps")
//resolveMainClassName.dependsOn("generateVersionProps")

jar {
dependsOn(generateVersionProps)
archiveFileName
}

bootJar {
enabled = false
}
//bootJar {
// enabled = false
//}
29 changes: 19 additions & 10 deletions mappingservice-plugin/integrationtests/basic.hurl
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,34 @@ HTTP 200
# Get mapping types from the mapping service
# to fetch the first available id
# ----------------------------------------------------------
GET {{host}}/api/v1/mappingAdministration/types
GET {{host}}/api/v1/mappingAdministration/plugins
HTTP 200
[Captures]
mappingType: jsonpath "$[0].id"
mappingType: regex "(?s)\"id\"\\s*:\\s*\"([^\"]+)\"\\s*,\\s*[^}]*?\"name\"\\s*:\\s*\"ApeHe_nxs2JSON\""

# ---------------- BEGIN Test Mapping for Ape-He -----------

# ----------------------------------------------------------
# Register a dummy mapping with created files:
# - record.json (containing the mapping scheme metadata)
# - document.json (containing the dummy map file)
# Register a dummy mapping with embedded JSON
# ----------------------------------------------------------
POST {{host}}/api/v1/mappingAdministration/
Content-Type: multipart/form-data; boundary=boundary
[Options]
variable: id1=96
[MultipartFormData]
record: file,record.json; type=application/json
document: file,document.json; type=application/json
HTTP 201 # Expect plugin to be successfully created
variable: id1=0
```
--boundary
Content-Disposition: form-data; name="record"; filename="blob"
Content-Type: application/json

{"mappingId":"{{id1}}","mappingType": "{{mappingType}}","title":"APE-HE from CI test","description":"","acl":[]}
--boundary
Content-Disposition: form-data; name="document"; filename="blob"
Content-Type: application/json

{"entry.title.value": "entry.title"}
--boundary--
```
HTTP 201

# ----------------------------------------------------------
# Execute mapping with test data
Expand Down
Original file line number Diff line number Diff line change
@@ -1,60 +1,15 @@
package edu.kit.datamanager.apeHeplugin;

import edu.kit.datamanager.mappingservice.plugins.*;
import edu.kit.datamanager.mappingservice.util.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.MimeType;
import org.springframework.util.MimeTypeUtils;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import edu.kit.datamanager.mappingservice.plugins.AbstractPythonMappingPlugin;
import java.nio.file.Path;
import java.util.Properties;

public class ApeHePlugin implements IMappingPlugin{

private static String version;
public class ApeHePlugin extends AbstractPythonMappingPlugin{

private final Logger LOGGER = LoggerFactory.getLogger(ApeHePlugin.class);
private final String REPOSITORY = "https://github.com/kit-data-manager/ape_he_mapper";
private String TAG;
private Path dir;
private static final String REPOSITORY = "https://github.com/kit-data-manager/ape_he_mapper";

//private String pluginVenv = "venv/PluginVenv";
//private String venvInterpreter;

public ApeHePlugin() {
try {
// Get the context class loader
ClassLoader classLoader = this.getClass().getClassLoader();
// TODO: do we need to make sure that the resource path is somehow related to the current plugin to avoid loading the wrong property file in case of identical property names?
URL resource = classLoader.getResource("apeHepluginversion.properties");
LOGGER.info("Resource file: {}", resource);
if (resource != null) {
// Load the properties file
try (InputStream input = resource.openStream()) {
Properties properties = new Properties();
properties.load(input);
version = properties.getProperty("version");
TAG = version;
}
} else {
System.err.println("Properties file not found!");
version = "unavailable";
TAG = "unavailable";
}

//if (System.getProperty("os.name").startsWith("Windows")) {
// venvInterpreter = pluginVenv + "/Scripts/python.exe";
//} else {
// venvInterpreter = pluginVenv + "/bin/python3";
//}

} catch (IOException e) {
e.printStackTrace();
}
super("ApeHe_nxs2JSON", REPOSITORY);
}

@Override
Expand All @@ -68,86 +23,32 @@ public String description() {
}

@Override
public String version() {
return version;
}

@Override
public String uri() {
return REPOSITORY;
}

@Override
public MimeType[] inputTypes() {
return new MimeType[]{
MimeTypeUtils.parseMimeType("application/octet-stream"),
MimeTypeUtils.parseMimeType("application/x-hdf5"),
MimeTypeUtils.parseMimeType("application/zip")
public String[] inputTypes() {
return new String[]{
"application/octet-stream",
"application/x-hdf5",
"application/zip"
};
}

@Override
public MimeType[] outputTypes() {
return new MimeType[]{
MimeTypeUtils.APPLICATION_JSON,
MimeTypeUtils.parseMimeType("application/zip")
public String[] outputTypes() {
return new String[]{
"application/json",
"application/zip"
};
}

@Override
public void setup() {
LOGGER.info("Checking and installing dependencies for the tool: ");
//TODO: test for minimal python version?
try {
LOGGER.info("Cloning git repository {}, Tag {}", REPOSITORY, TAG);
dir = FileUtil.cloneGitRepository(REPOSITORY, TAG);
// Install Python dependencies

ProcessBuilder pb = new ProcessBuilder("python3", "-m", "pip", "install", "-r", dir + "/requirements.dist.txt");
pb.inheritIO();
Process p = pb.start();

int exitCode = p.waitFor();
if (exitCode != 0) {
LOGGER.error("Failed to install Python packages");
}

} catch (Exception e) {
e.printStackTrace();
}
}
/* public void setup() {
LOGGER.trace("Setting up mapping plugin {} {}", name(), version());
//TODO: test for minimal python version?
try {
LOGGER.info("Cloning git repository {}, Tag {}", REPOSITORY, TAG);
dir = FileUtil.cloneGitRepository(REPOSITORY, TAG);
// Install Python dependencies

MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", dir + "/" + pluginVenv);
if (MappingPluginState.SUCCESS().getState().equals(venvState.getState())) {
LOGGER.info("Venv for plugin installed successfully.");
LOGGER.info("Installing packages");
ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt");
} else {
LOGGER.error("venv installation was not successful");
}

} catch (Exception e) {
e.printStackTrace();
}
} */

@Override
public MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException {
long startTime = System.currentTimeMillis();
LOGGER.trace("Run ApeHe-Mapping-Tool on '{}' with mapping '{}' -> '{}'", mappingFile, inputFile, outputFile);
//MappingPluginState result = ShellRunnerUtil.run(dir + "/" + venvInterpreter, dir + "/plugin_wrapper.py", "-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString());
String[] args = {"-m", mappingFile.toString(), "-i", inputFile.toString(), "-o", outputFile.toString()};
MappingPluginState result = PythonRunnerUtil.runPythonScript(dir + "/plugin_wrapper.py", args);
long endTime = System.currentTimeMillis();
long totalTime = endTime - startTime;
LOGGER.info("Execution time of mapFile: {} milliseconds", totalTime);
return result;
public String[] getCommandArray(Path workingDir, Path mappingFile, Path inputFile, Path outputFile) {
return new String[]{
workingDir + "/plugin_wrapper.py",
"-m",
mappingFile.toString(),
"-i",
inputFile.toString(),
"-o",
outputFile.toString()
};
}
}
Binary file not shown.
Loading