Skip to content

Commit d8c9be7

Browse files
authored
Merge branch 'development' into renovate/edu.kit.datamanager-service-base-1.x
2 parents 778c109 + 45d9a40 commit d8c9be7

File tree

21 files changed

+71
-593
lines changed

21 files changed

+71
-593
lines changed

build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ dependencies {
8888
exclude group: "com.sun.xml.bind"
8989
}
9090
// apache
91-
implementation "org.apache.tika:tika-core:2.9.3"
91+
implementation "org.apache.tika:tika-core:3.1.0"
9292

9393
testImplementation platform('org.junit:junit-bom')
9494
testImplementation 'org.junit.jupiter:junit-jupiter'

src/main/java/edu/kit/datamanager/mappingservice/impl/MappingService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,6 +498,11 @@ private void init(ApplicationProperties applicationProperties) {
498498
} catch (IOException e) {
499499
throw new MappingServiceException(String.format("Could not initialize job output directory '%s'.", applicationProperties.getJobOutputLocation()), e);
500500
}
501+
try {
502+
Files.createDirectories(new File(applicationProperties.getCodeLocation().getPath()).getAbsoluteFile().toPath());
503+
} catch (IOException e) {
504+
throw new MappingServiceException(String.format("Could not initialize code target directory '%s'.", applicationProperties.getCodeLocation()), e);
505+
}
501506
} else {
502507
throw new MappingServiceException("Cannot configure MappingService due to missing application.properties.");
503508
}

src/main/java/edu/kit/datamanager/mappingservice/plugins/AbstractPythonMappingPlugin.java

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,6 @@ public abstract class AbstractPythonMappingPlugin implements IMappingPlugin {
4444

4545
private final Logger LOGGER = LoggerFactory.getLogger(AbstractPythonMappingPlugin.class);
4646

47-
/**
48-
* Application properties autowired at instantiation time via
49-
* setApplicationProperties.
50-
*/
51-
private ApplicationProperties applicationProperties;
5247
/**
5348
* The plugin name.
5449
*/
@@ -129,17 +124,6 @@ public AbstractPythonMappingPlugin(String pluginName, String repositoryUrl) {
129124
}
130125
}
131126

132-
/**
133-
* Setter to autowire ApplicationProperties into all implementations of this
134-
* abstract class.
135-
*
136-
* @param applicationProperties The applicationProperties bean.
137-
*/
138-
@Autowired
139-
public final void setApplicationProperties(ApplicationProperties applicationProperties) {
140-
this.applicationProperties = applicationProperties;
141-
}
142-
143127
/**
144128
* Abstract method that is supposed to be implemented by each Python mapping
145129
* plugin to gather all information required for starting a Python process
@@ -198,7 +182,7 @@ public String uri() {
198182
}
199183

200184
@Override
201-
public void setup() {
185+
public void setup(ApplicationProperties applicationProperties) {
202186
LOGGER.trace("Setting up mapping plugin {} {}", name(), version());
203187

204188
//testing minimal Python version
@@ -211,16 +195,25 @@ public void setup() {
211195
//checkout and install plugin
212196
try {
213197
LOGGER.info("Cloning git repository {}, tag {}", repositoryUrl, tag);
214-
dir = FileUtil.cloneGitRepository(repositoryUrl, tag, Paths.get(applicationProperties.getCodeLocation().toURI()).toAbsolutePath().toString());
198+
Path path = Paths.get(applicationProperties.getCodeLocation().toURI());
199+
path = path.resolve(repositoryUrl.trim().replace("https://", "").replace("http://", "").replace(".git", "") + "_" + version());
200+
LOGGER.info("Target path: {}", path);
201+
dir = FileUtil.cloneGitRepository(repositoryUrl, tag, path.toAbsolutePath().toString());
215202
// Install Python dependencies
216203
MappingPluginState venvState = PythonRunnerUtil.runPythonScript("-m", "venv", "--system-site-packages", dir + "/" + pluginVenv);
217204
if (MappingPluginState.SUCCESS().getState().equals(venvState.getState())) {
218-
LOGGER.info("Venv for plugin installed successfully. Installing packages.");
219-
MappingPluginState requirementsInstallState = ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt");
220-
if (MappingPluginState.SUCCESS().getState().equals(requirementsInstallState.getState())) {
221-
LOGGER.info("Requirements for plugin installed successfully. Setup complete.");
205+
LOGGER.info("Venv for plugin installed successfully. Installing requirements.");
206+
207+
Path requirementsFile = Paths.get(dir + "/" + "requirements.dist.txt");
208+
if (requirementsFile.toFile().exists()) {
209+
MappingPluginState requirementsInstallState = ShellRunnerUtil.run(dir + "/" + venvInterpreter, "-m", "pip", "install", "-r", dir + "/" + "requirements.dist.txt");
210+
if (MappingPluginState.SUCCESS().getState().equals(requirementsInstallState.getState())) {
211+
LOGGER.info("Requirements for plugin installed successfully. Setup complete.");
212+
} else {
213+
throw new PluginInitializationFailedException("Failed to install plugin requirements. Status: " + venvState.getState());
214+
}
222215
} else {
223-
throw new PluginInitializationFailedException("Failed to install plugin requirements. Status: " + venvState.getState());
216+
LOGGER.info("No requirements file found. Skipping dependency installation.");
224217
}
225218
} else {
226219
throw new PluginInitializationFailedException("Venv installation has failed. Status: " + venvState.getState());
@@ -267,10 +260,7 @@ private boolean hasMinimalPythonVersion(String versionString) {
267260
try {
268261
LOGGER.trace("Checking for minimal Python version {}.", versionString);
269262
ByteArrayOutputStream bout = new ByteArrayOutputStream();
270-
List<String> command = new LinkedList<>();
271-
command.add(dir + "/" + venvInterpreter);
272-
command.addAll(Arrays.asList("--version"));
273-
MappingPluginState state = ShellRunnerUtil.run(bout, System.err, command.toArray(String[]::new));
263+
MappingPluginState state = PythonRunnerUtil.runPythonScript("--version", bout, System.err);
274264

275265
if (!MappingPluginState.StateEnum.SUCCESS.equals(state.getState())) {
276266
LOGGER.error("Failed to obtain Python version. python --version returned with status {}.", state.getState());

src/main/java/edu/kit/datamanager/mappingservice/plugins/IMappingPlugin.java

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,17 @@
1212
* See the License for the specific language governing permissions and
1313
* limitations under the License.
1414
*/
15-
1615
package edu.kit.datamanager.mappingservice.plugins;
1716

17+
import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties;
1818
import org.springframework.util.MimeType;
1919

2020
import java.nio.file.Path;
2121

2222
/**
23-
* Interface for mapping plugins.
24-
* Every plugin which implements this interface and is placed in the plugins folder will be loaded and usable via the REST-API.
23+
* Interface for mapping plugins. Every plugin which implements this interface
24+
* and is placed in the plugins folder will be loaded and usable via the
25+
* REST-API.
2526
*
2627
* @author maximilianiKIT
2728
*/
@@ -42,15 +43,17 @@ public interface IMappingPlugin {
4243
String description();
4344

4445
/**
45-
* The version of the plugin which gets displayed in the UI and is part of the id.
46+
* The version of the plugin which gets displayed in the UI and is part of
47+
* the id.
4648
*
4749
* @return The version of the plugin.
4850
*/
4951
String version();
5052

5153
/**
52-
* A URI which refers to the plugin or the technology used by the plugin (e.g. a link to a GitHub repository).
53-
* This URI will be displayed in the UI.
54+
* A URI which refers to the plugin or the technology used by the plugin
55+
* (e.g. a link to a GitHub repository). This URI will be displayed in the
56+
* UI.
5457
*
5558
* @return The URI of the plugin.
5659
*/
@@ -71,8 +74,9 @@ public interface IMappingPlugin {
7174
MimeType[] outputTypes();
7275

7376
/**
74-
* The id of the plugin which is used to identify the plugin.
75-
* By default, the id is composed of the name and the version of the plugin (e.g. testPlugin_2.1.0).
77+
* The id of the plugin which is used to identify the plugin. By default,
78+
* the id is composed of the name and the version of the plugin (e.g.
79+
* testPlugin_2.1.0).
7680
*
7781
* @return The id of the plugin.
7882
*/
@@ -81,19 +85,22 @@ default String id() {
8185
}
8286

8387
/**
84-
* This method is called when the plugin is loaded.
85-
* It can be used to initialize the plugin and install dependencies.
88+
* This method is called when the plugin is loaded. It can be used to
89+
* initialize the plugin and install dependencies.
90+
*
91+
* @param applicationProperties Properties object containing all
92+
* mapping-service settings.
8693
*/
87-
void setup();
94+
void setup(ApplicationProperties applicationProperties);
8895

8996
/**
9097
* The method which is called to execute the plugin.
9198
*
92-
* @param inputFile The path to the output document.
93-
* @param outputFile The path to the output document.
99+
* @param inputFile The path to the output document.
100+
* @param outputFile The path to the output document.
94101
* @param mappingFile The path to the mapping schema.
95102
* @return The exit code of the plugin.
96-
*
103+
*
97104
* @throws MappingPluginException If the mapping execution fails.
98105
*/
99106
MappingPluginState mapFile(Path mappingFile, Path inputFile, Path outputFile) throws MappingPluginException;

src/main/java/edu/kit/datamanager/mappingservice/plugins/PluginLoader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ public Map<String, IMappingPlugin> loadPlugins(File pluginDir, String[] packages
100100
cl = Thread.currentThread().getContextClassLoader();
101101
}
102102

103-
List<Class<IMappingPlugin>> plugClasses = extractClassesFromJARs(pluginJars, packagesToScan, cl);
104-
List<IMappingPlugin> IMappingPluginList = createPluggableObjects(plugClasses);
103+
List<Class<IMappingPlugin>> pluginClasses = extractClassesFromJARs(pluginJars, packagesToScan, cl);
104+
List<IMappingPlugin> IMappingPluginList = createPluggableObjects(pluginClasses);
105105

106106
for (IMappingPlugin i : IMappingPluginList) {
107107
try {
108-
i.setup();
108+
i.setup(applicationProperties);
109109
LOG.trace(" - Adding new plugin {}, v{} to available list", i.name(), i.version());
110110
result.put(i.id(), i);
111111
} catch (PluginInitializationFailedException re) {

src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/IdentifyPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package edu.kit.datamanager.mappingservice.plugins.impl;
1717

18+
import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties;
1819
import edu.kit.datamanager.mappingservice.exception.PluginInitializationFailedException;
1920
import edu.kit.datamanager.mappingservice.plugins.IMappingPlugin;
2021
import edu.kit.datamanager.mappingservice.plugins.MappingPluginException;
@@ -71,7 +72,7 @@ public MimeType[] outputTypes() {
7172
}
7273

7374
@Override
74-
public void setup() {
75+
public void setup(ApplicationProperties applicationProperties) {
7576
if (Paths.get("/usr/bin/identify").toFile().exists()) {
7677
initialized = true;
7778
} else {

src/main/java/edu/kit/datamanager/mappingservice/plugins/impl/InOutPlugin.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package edu.kit.datamanager.mappingservice.plugins.impl;
1717

18+
import edu.kit.datamanager.mappingservice.configuration.ApplicationProperties;
1819
import edu.kit.datamanager.mappingservice.exception.MappingException;
1920
import edu.kit.datamanager.mappingservice.plugins.IMappingPlugin;
2021
import edu.kit.datamanager.mappingservice.plugins.MappingPluginException;
@@ -66,7 +67,7 @@ public MimeType[] outputTypes() {
6667
}
6768

6869
@Override
69-
public void setup() {
70+
public void setup(ApplicationProperties applicationProperties) {
7071
//nothing to do here
7172
LOG.trace("Plugin {} {} successfully set up.", name(), version());
7273
}

src/main/java/edu/kit/datamanager/mappingservice/util/FileUtil.java

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -294,27 +294,34 @@ private static String guessFileExtension(String filename, byte[] fewKilobytesOfF
294294
public static Path cloneGitRepository(String repositoryUrl, String branch, String targetFolder) {
295295
File target = new File(targetFolder);
296296
if (target.exists()) {
297+
Git g = null;
297298
try {
298-
try (Git g = Git.open(target)) {
299-
LOGGER.trace("Repository already exists at {}. Active branch is: {}", target, g.getRepository().getBranch());
300-
g.getRepository().close();
301-
}
299+
g = Git.open(target);
300+
LOGGER.trace("Repository already exists at {}. Active branch is: {}", target, g.getRepository().getBranch());
302301
} catch (IOException e) {
303302
String message = String.format("Folder '%s' already exists but contains not Git repository.", target);
304303
LOGGER.error(message, e);
305304
throw new MappingServiceException("Failed to prepare plugin. Plugin code destination already exists but is empty.");
305+
} finally {
306+
if (g != null) {
307+
g.getRepository().close();
308+
}
306309
}
307310
} else {
308311
target.mkdirs();
309312

310313
LOGGER.info("Cloning branch '{}' of repository '{}' to '{}'", branch, repositoryUrl, target.getPath());
314+
Git g = null;
311315
try {
312-
try (Git res = Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call()) {
313-
res.getRepository().close();
314-
}
316+
g = Git.cloneRepository().setURI(repositoryUrl).setBranch(branch).setDirectory(target).call();
317+
LOGGER.trace("Repository successfully cloned to {}.", target);
315318
} catch (JGitInternalException | GitAPIException e) {
316319
LOGGER.error("Error cloning git repository '" + repositoryUrl + "' to '" + target + "'!", e);
317320
throw new MappingServiceException("Failed to prepare plugin. Plugin code destination not accessible.");
321+
} finally {
322+
if (g != null) {
323+
g.getRepository().close();
324+
}
318325
}
319326
}
320327
return target.toPath();

src/main/resources/gemma.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
version=master
1+
version=v1.0.0
22
min.python=3.0.0

src/test/java/edu/kit/datamanager/mappingservice/plugins/PluginLoaderTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void valid() {
7373
assertEquals("https://github.com/kit-data-manager/mapping-service", plugins.get("InOutPlugin_1.1.2").uri());
7474
assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").inputTypes()[0].toString());
7575
assertEquals("application/*", plugins.get("InOutPlugin_1.1.2").outputTypes()[0].toString());
76-
plugins.get("InOutPlugin_1.1.2").setup();
76+
plugins.get("InOutPlugin_1.1.2").setup(applicationProperties);
7777
File inputFile = new File("/tmp/imputFile");
7878
if (!inputFile.exists()) {
7979
Assertions.assertTrue(inputFile.createNewFile());

src/test/java/edu/kit/datamanager/mappingservice/rest/impl/MappingAdministrationControllerTest.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public class MappingAdministrationControllerTest {
9292

9393
private final static String TEMP_DIR_4_MAPPING = "/tmp/mapping-service/";
9494
private static final String MAPPING_ID = "my_dc";
95-
private static final String MAPPING_TYPE = "GEMMA_1.0.0";
95+
private static final String MAPPING_TYPE = "GEMMA_v1.0.0";
9696
private static final String MAPPING_TITLE = "TITEL";
9797
private static final String MAPPING_DESCRIPTION = "DESCRIPTION";
9898

@@ -890,7 +890,7 @@ public void testDeleteMappingUnknownMappingId() throws JsonProcessingException,
890890
result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isNoContent()).andReturn();
891891
// assertEquals(1, mappingsDir.list().length);
892892
String expectedFilename = mappingId + "_" + mappingType + ".mapping";
893-
assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename);
893+
assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename);
894894
assertEquals(1, mappingRecordDao.count());
895895
}
896896

@@ -935,7 +935,7 @@ public void testDeleteMappingMissingEtag() throws JsonProcessingException, Excep
935935
result = this.mockMvc.perform(delete(deleteMappingIdUrl)).andDo(print()).andExpect(status().isPreconditionRequired()).andReturn();
936936
// assertEquals(1, mappingsDir.list().length);
937937
String expectedFilename = mappingId + "_" + mappingType + ".mapping";
938-
assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename);
938+
assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename);
939939
result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn();
940940
assertEquals(1, mappingRecordDao.count());
941941
}
@@ -959,7 +959,7 @@ public void testDeleteMappingWrongEtag() throws JsonProcessingException, Excepti
959959
result = this.mockMvc.perform(delete(deleteMappingIdUrl).header("If-Match", etag)).andDo(print()).andExpect(status().isPreconditionFailed()).andReturn();
960960
// assertEquals(1, mappingsDir.list().length);
961961
String expectedFilename = mappingId + "_" + mappingType + ".mapping";
962-
assertEquals("my_dc_GEMMA_1.0.0.mapping", expectedFilename);
962+
assertEquals("my_dc_" + MAPPING_TYPE + ".mapping", expectedFilename);
963963
result = this.mockMvc.perform(get(getMappingIdUrl).header("Accept", MappingRecord.MAPPING_RECORD_MEDIA_TYPE)).andDo(print()).andExpect(status().isOk()).andReturn();
964964
assertEquals(1, mappingRecordDao.count());
965965
}

0 commit comments

Comments
 (0)