Skip to content

Commit c3a7371

Browse files
authored
Merge pull request #20 from kit-data-manager/19-Improper_handling_of_mapping_results
19 improper handling of mapping results
2 parents ec090d2 + 25e4009 commit c3a7371

32 files changed

+1116
-664
lines changed

.github/workflows/CI.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ jobs:
4545
# run: ./gradlew build -DapplicationProperties="src\test\resources\test-config\application-test-windows.properties"
4646
- if: matrix.os != 'windows-latest'
4747
name: Test with Gradle on ${{ matrix.os }}
48-
run: ./gradlew build -DapplicationProperties="src/test/resources/test-config/application-test.properties"
48+
run: ./gradlew build -DapplicationProperties="src/test/resources/test-config/application-test.properties" -DpythonLocation=`which python3`
4949
- name: Generate report
5050
run: ./gradlew jacocoTestReport
5151
- name: Codecov
5252
uses: codecov/codecov-action@v1
5353
with:
54-
files: ./build/reports/jacoco/test/jacocoTestReport.xml
54+
files: ./build/reports/jacoco/test/jacocoTestReport.xml

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#!gradle/wrapper/gradle-wrapper.jar
55
#!**/src/main/**/build/
66
#!**/src/test/**/build/
7+
lib/
78
#
89
#### Spring boot ###
910
**/application.properties

README.md

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,44 +21,61 @@ Dependencies that are needed to build and are not being downloaded via gradle:
2121

2222
- OpenJDK 17
2323
- Python 3
24-
- pip
24+
- pip (runtime only)
2525

2626
`./gradlew -Pclean-release build`
2727

2828
### Python Location
2929

30-
Currently, mapping-service requires Python to be installed in order to build and to run. By default, the Python location is set to `/usr/bin/python3`. In case
31-
your Python installation is located elsewhere or you build the mapping-service under Windows, you can provide the Python location externally, i.e.:
30+
Currently, mapping-service requires Python to be installed in order to build and to run. At runtime, the Python executable is configured in
31+
`application.properties`(see below). For building the mapping-service Python executable is set to `/usr/bin/python3` by default. In case you want to build
32+
the mapping-service on a machine on which the Python installation is located elsewhere, e.g., under Windows, you can provide the Python location
33+
used at compile time externally, i.e.:
3234

3335
```
34-
`./gradlew -Pclean-release build -DpythonLocation=file:///C:/Python310/python.EXE`
36+
.\gradlew -Pclean-release "-DpythonExecutable=file:///C:/Python310/python.exe" build
3537
```
3638

3739
## How to start
3840

3941
Before you can start the mapping-service, you first have to create an `application.properties` file in the source folder. As an example you may use `config/application.default.properties`
4042
and modify it according to your needs. Espacially the following properties (at the end of the file) are important:
41-
- `spring.datasource.url=jdbc:h2:file:e:/tmp/mapping-service/database`
43+
- `spring.datasource.url=jdbc:h2:file:/tmp/mapping-service/database`
4244
The path points to the location of the database in which your configured mappings are stored.
43-
- `mapping-service.pythonLocation=${pythonLocation:'file:///usr/bin/python3'}` \
44-
If no pythonLocation is provided externally (see above) the default `/usr/bin/python3` is used.
45+
- `mapping-service.pythonExecutable=${pythonExecutable:'file:///usr/bin/python3'}` \
46+
If no pythonExecutable is provided externally (see above) the default `/usr/bin/python3` is used.
47+
- `mapping-service.pluginLocation=file:///tmp/mapping-service/plugins` \
48+
The local folder where available plugins are located.
4549
- `mapping-service.mappingsLocation:file:///tmp/mapping-service/` \
4650
Enter the location where you want to store your mappings. This folder will be created if it does not exist yet.
4751

48-
You might want to add a plugin to make the service working. Normally, there should be a gemma-plugin-x.x.x.jar in the plugins folder.
49-
If not, you can find its source code [here](https://github.com/maximilianiKIT/gemma-plugin).
52+
In order to provide the mapping-service with mapping functionality, there are already some pre-compiled plugins available under in the `plugins` folder of this repository.
53+
Copy them to your configured `mapping-service.pluginLocation` to make them available to the mapping-service.
54+
The source code of the gemma-plugin can be found [here](https://github.com/maximilianiKIT/gemma-plugin). The plugin shows how to integrate Python mappings easily.
55+
56+
There is also the possibility to add new plugins directly at the source tree and create a pluggable Jar out of them. Therefor, check
57+
`src/main/java/edu/kit/datamanager/mappingservice/plugins/impl`. Just add your new plugin, e.g., based on the `TestPlugin` example.
58+
In order to make the plugin usable by the mapping service, you then have to build a plugin Jar out of it. In order to do that, just call:
59+
60+
```
61+
./gradlew buildPluginJar
62+
```
63+
64+
This task creates a file `default-plugins-<VERSION>` at `build/libs` which has to be copied to `mapping-service.pluginLocation` to make it available.
5065

5166
After doing this, the mapping-service is ready for the first start. This can be achieved by executing:
5267

53-
`./gradlew bootRun`
68+
`java -jar build/lib/mapping-service-<VERSION>.jar`
5469

55-
### Python Location
70+
This assumes, that the command is called from the source folder and that your `application.properties` is located in the same folder.
71+
Otherwise, you may use:
5672

57-
Similar to configuring the Python location for the build process, you may also do the same for running the mapping-service via:
73+
`java -jar build/lib/mapping-service-<VERSION>.jar --spring.config.location=/tmp/application.properties`
5874

59-
```
60-
.\gradlew -DpythonLocation=file:///C:/Python310/python.EXE bootRun
61-
```
75+
Ideally, for production use, you place everything (`mapping-service-<VERSION>.jar`, `application.properties`, `mapping-service.pluginLocation`, `mapping-service.mappingsLocation`,
76+
and `spring.datasource.url`) in a separate folder from where you then call the mapping-service via:
77+
78+
`java -jar mapping-service-<VERSION>.jar`
6279

6380
## License
6481

build.gradle

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ repositories {
3636
ext {
3737
set('snippetsDir', file('build/generated-snippets'))
3838
applicationProperties = System.getProperty('applicationProperties', './src/test/resources/test-config/application-test.properties')
39-
pythonLocation = System.getProperty('pythonLocation', 'file:///usr/bin/python3')
39+
pythonExecutable = System.getProperty('pythonExecutable', 'file:///usr/bin/python3')
40+
userDir = System.getProperty('user.dir')
4041
}
4142

4243
dependencies {
@@ -89,11 +90,13 @@ dependencies {
8990
test {
9091
outputs.dir snippetsDir
9192
finalizedBy jacocoTestReport
92-
print("Running tests with configuration: ${applicationProperties}")
93+
println("Running tests with configuration: ${applicationProperties}")
94+
println("Running tests with python: ${pythonExecutable}")
95+
println("Running tests in directory: ${userDir}")
9396
environment 'spring.config.location', applicationProperties
94-
environment 'pythonLocation', pythonLocation
95-
// environment 'spring.config.location', 'classpath:/test-config/'
97+
environment 'pythonExecutable', pythonExecutable
9698
useJUnitPlatform()
99+
testLogging.showStandardStreams = true
97100
}
98101

99102
jacoco {
@@ -126,7 +129,7 @@ springBoot {
126129

127130
bootRun {
128131
systemProperty "spring.config.location", "file:$projectDir/"
129-
systemProperty "pythonLocation", pythonLocation
132+
systemProperty "pythonLocation", pythonExecutable
130133
}
131134

132135
bootJar {
@@ -140,3 +143,10 @@ bootJar {
140143
release {
141144
tagTemplate = 'v${version}'
142145
}
146+
147+
task buildPluginJar(type: Jar) {
148+
description = 'Bundeling only plugin classes'
149+
archiveFileName.set("default-plugins-${version}.jar")
150+
from sourceSets.main.output
151+
include '**/plugins/impl/*.class'
152+
}

config/application.default.properties

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ server.port=8095
66
# The properties max-file-size and max-request-size define the maximum size of files
77
# transferred to and from the repository. Setting them to -1 removes all limits.
88
server.compression.enabled=false
9+
10+
# Max sizes of requests and uploaded files. This value may has to be increased for
11+
# bigger mapping inputs, e.g., while extracting information for a zipped dataset.
912
spring.servlet.multipart.max-file-size=100MB
1013
spring.servlet.multipart.max-request-size=100MB
1114
# Logging settings
@@ -32,8 +35,9 @@ spring.jpa.hibernate.ddl-auto=update
3235
##################################################
3336
# Mapping-Service specific settings
3437
##################################################
35-
# Absolute path to the local python interpreter
38+
# Absolute path to the local python interpreter.
3639
mapping-service.pythonLocation=${pythonLocation:'file:///usr/bin/python3'}
37-
38-
# Absolute path to the local gemma mappings folder
40+
# Absolute path to the folder where all plugins are located.
41+
mapping-service.pluginLocation=file:///${user.dir}/plugins
42+
# Absolute path to the local gemma mappings folder.
3943
mapping-service.mappingSchemasLocation=file:///tmp/mapping-service/mappingSchemas

src/main/java/edu/kit/datamanager/mappingservice/MappingServiceApplication.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,16 @@ public ApplicationProperties applicationProperties() {
2424
return new ApplicationProperties();
2525
}
2626

27+
@Bean
28+
public PluginManager pluginManager(){
29+
return new PluginManager(applicationProperties());
30+
}
31+
2732
public static void main(String[] args) {
2833
SpringApplication.run(MappingServiceApplication.class, args);
2934

30-
PluginManager.soleInstance().getListOfAvailableValidators().forEach((value) -> LOG.info("Found validator: " + value));
31-
PythonRunnerUtil.printPythonVersion();
35+
//pluginManager().getListOfAvailableValidators().forEach((value) -> LOG.info("Found validator: " + value));
36+
//PythonRunnerUtil.printPythonVersion();
3237

3338
System.out.println("Mapping service is running! Access it at http://localhost:8095");
3439
}

src/main/java/edu/kit/datamanager/mappingservice/configuration/ApplicationProperties.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717

1818
import edu.kit.datamanager.annotations.ExecutableFileURL;
1919
import edu.kit.datamanager.annotations.LocalFolderURL;
20-
import edu.kit.datamanager.configuration.GenericPluginProperties;
2120
import lombok.Data;
2221
import lombok.EqualsAndHashCode;
2322
import org.springframework.beans.factory.annotation.Value;
@@ -28,8 +27,8 @@
2827
import java.net.URL;
2928

3029
/**
31-
* This class is used to configure the application.
32-
* It reads the values from the application.properties file.
30+
* This class is used to configure the application. It reads the values from the
31+
* application.properties file.
3332
*
3433
* @author maximilianiKIT
3534
*/
@@ -39,12 +38,20 @@
3938
@Validated
4039
@EqualsAndHashCode
4140
public class ApplicationProperties {
41+
4242
/**
4343
* The absolute path to the python interpreter.
4444
*/
4545
@ExecutableFileURL
46-
@Value("${mapping-service.pythonLocation}")
47-
private URL pythonLocation;
46+
@Value("${mapping-service.pythonExecutable}")
47+
private URL pythonExecutable;
48+
49+
/**
50+
* The absolute path where the plugins are stored.
51+
*/
52+
@LocalFolderURL
53+
@Value("${mapping-service.pluginLocation}")
54+
private URL pluginLocation;
4855

4956
/**
5057
* The absolute path where the mappings are stored.
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2022 Karlsruhe Institute of Technology.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package edu.kit.datamanager.mappingservice.exception;
17+
18+
import org.springframework.http.HttpStatus;
19+
import org.springframework.web.bind.annotation.ResponseStatus;
20+
21+
/**
22+
* Invalid json format of data.
23+
*/
24+
@ResponseStatus(value = HttpStatus.CONFLICT)
25+
public class DuplicateMappingException extends RuntimeException {
26+
27+
/**
28+
* Default constructor.
29+
*/
30+
public DuplicateMappingException() {
31+
super();
32+
}
33+
34+
/**
35+
* Constructor with given message and cause.
36+
*
37+
* @param message Message.
38+
* @param cause Cause.
39+
*/
40+
public DuplicateMappingException(String message, Throwable cause) {
41+
super(message, cause);
42+
}
43+
44+
/**
45+
* Constructor with given message.
46+
*
47+
* @param message Message.
48+
*/
49+
public DuplicateMappingException(String message) {
50+
super(message);
51+
}
52+
53+
/**
54+
* Constructor with given message and cause.
55+
*
56+
* @param cause Cause.
57+
*/
58+
public DuplicateMappingException(Throwable cause) {
59+
super(cause);
60+
}
61+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2022 Karlsruhe Institute of Technology.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package edu.kit.datamanager.mappingservice.exception;
17+
18+
import org.springframework.http.HttpStatus;
19+
import org.springframework.web.bind.annotation.ResponseStatus;
20+
21+
/**
22+
* Invalid json format of data.
23+
*/
24+
@ResponseStatus(value = HttpStatus.NOT_FOUND)
25+
public class MappingNotFoundException extends RuntimeException {
26+
27+
/**
28+
* Default constructor.
29+
*/
30+
public MappingNotFoundException() {
31+
super();
32+
}
33+
34+
/**
35+
* Constructor with given message and cause.
36+
*
37+
* @param message Message.
38+
* @param cause Cause.
39+
*/
40+
public MappingNotFoundException(String message, Throwable cause) {
41+
super(message, cause);
42+
}
43+
44+
/**
45+
* Constructor with given message.
46+
*
47+
* @param message Message.
48+
*/
49+
public MappingNotFoundException(String message) {
50+
super(message);
51+
}
52+
53+
/**
54+
* Constructor with given message and cause.
55+
*
56+
* @param cause Cause.
57+
*/
58+
public MappingNotFoundException(Throwable cause) {
59+
super(cause);
60+
}
61+
}

0 commit comments

Comments
 (0)