Skip to content
This repository has been archived by the owner on Apr 17, 2021. It is now read-only.

Commit

Permalink
Parser: new VaultPreprocessing component for performing compatibility…
Browse files Browse the repository at this point in the history
… adjustments and other last-minute changes over uncontrolled inputs, right before compilation happens
  • Loading branch information
eledhwen committed Jan 25, 2021
1 parent f3c6e81 commit 79a1201
Show file tree
Hide file tree
Showing 9 changed files with 178 additions and 4 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Add the following in your `pom.xml`:
<dependency>
<groupId>com.lumiomedical</groupId>
<artifactId>lumio-vault</artifactId>
<version>0.9.1</version>
<version>0.10</version>
</dependency>
```

Expand Down Expand Up @@ -93,6 +93,7 @@ Other features that will need to be documented include:
* service closing
* service container composition
* custom modules
* custom preprocessing routines

_TODO_

Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>com.lumiomedical</groupId>
<artifactId>lumio-vault</artifactId>
<version>0.9.1</version>
<version>0.10</version>
<packaging>jar</packaging>

<name>Lumio Vault</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.lumiomedical.vault.exception.VaultStructureException;
import com.lumiomedical.vault.parser.adjuster.VaultAdjuster;
import com.lumiomedical.vault.parser.module.*;
import com.lumiomedical.vault.parser.preprocessor.VaultPreprocessor;
import com.lumiomedical.vault.parser.resolver.FlexibleResolver;
import com.lumiomedical.vault.parser.resolver.VaultResolver;
import com.lumiomedical.vault.parser.resolver.source.Source;
Expand All @@ -27,6 +28,7 @@ public class VaultCompositeParser implements VaultParser
private final VaultResolver resolver;
private static final String rootIdentifier = "*";
private static final Set<String> coreDirectives = Set.of("imports");
private final List<VaultPreprocessor> preprocessors = new ArrayList<>();
/* Module stacks */
private final List<VaultModule> preModules = Lists.of(
new VariableRegistrationModule()
Expand Down Expand Up @@ -110,6 +112,11 @@ private ObjectNode compileNode(Source source, ObjectNode rootNode) throws VaultP
{
try {
ObjectNode json = source.interpret();

/* The preprocessor pass can be used to perform compatibility adjustments or last-minute changes over uncontrolled inputs */
for (VaultPreprocessor preprocessor : this.preprocessors)
json = preprocessor.preprocess(json);

this.validateStructure(json);

for (String imp : this.getImports(json))
Expand Down Expand Up @@ -156,6 +163,12 @@ private ObjectNode compileNode(Source source, ObjectNode rootNode) throws VaultP
}
}

@Override
public VaultParser registerPreprocessor(VaultPreprocessor preprocessor)
{
this.preprocessors.add(preprocessor);
return this;
}

@Override
public VaultParser register(VaultModule module)
Expand Down
12 changes: 11 additions & 1 deletion src/main/java/com/lumiomedical/vault/parser/VaultParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import com.lumiomedical.vault.exception.VaultParserException;
import com.lumiomedical.vault.parser.adjuster.VaultAdjuster;
import com.lumiomedical.vault.parser.module.VaultModule;
import com.lumiomedical.vault.parser.preprocessor.VaultPreprocessor;
import com.lumiomedical.vault.parser.resolver.source.Source;

import java.util.Arrays;
Expand Down Expand Up @@ -81,8 +82,17 @@ default Definitions extractOrigin(Collection<String> origins, Definitions defini
Definitions extractOrigin(Collection<String> origins, Definitions definitions, Collection<VaultAdjuster> adjusters) throws VaultParserException;

/**
* Register a custom preprocessor for performing modifications over configuration nodes before compilation passes.
*
* @param module
* @param preprocessor a vault preprocessor instance
* @return
*/
VaultParser registerPreprocessor(VaultPreprocessor preprocessor);

/**
* Register a custom module for performing additional processing over configuration nodes.
*
* @param module a vault module instance
* @return
*/
VaultParser register(VaultModule module);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.lumiomedical.vault.parser.preprocessor;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.lumiomedical.vault.exception.VaultParserException;

/**
* The preprocessors are expected to be used to perform compatibility adjustments or last-minute changes over uncontrolled inputs.
* Preprocessing should happen before structure validation and before compilation.
*
* @author Pierre Lecerf (plecerf@lumiomedical.com)
* Created on 2021/01/25
*/
public interface VaultPreprocessor
{
/**
* Can alter a given configuration node, or leave it as is, before it goes through compilation.
*
* @param node A configuration node
* @return an altered configuration node
* @throws VaultParserException
*/
ObjectNode preprocess(ObjectNode node) throws VaultParserException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void basicYamlParsing() throws VaultParserException
makeAssertions(def);
}

void makeAssertions(Definitions def)
public static void makeAssertions(Definitions def)
{
Assertions.assertEquals(true, def.getVariable("provider.boolean.value"));
Assertions.assertEquals(12.34, def.getVariable("provider.double.value"));
Expand Down
64 changes: 64 additions & 0 deletions src/test/java/com/lumiomedical/vault/parser/PreprocessorTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.lumiomedical.vault.parser;

import com.fasterxml.jackson.databind.node.ObjectNode;
import com.lumiomedical.vault.container.definition.Definitions;
import com.lumiomedical.vault.exception.VaultParserException;
import com.noleme.json.Json;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

import static com.noleme.commons.function.RethrowConsumer.rethrower;

/**
* @author Pierre Lecerf (plecerf@lumiomedical.com)
* Created on 2020/11/24
*/
public class PreprocessorTest
{
@Test
void test() throws VaultParserException
{
var parser = new VaultCompositeParser();

Assertions.assertThrows(VaultParserException.class, () -> {
parser.extract("com/lumiomedical/vault/parser/simple.old_style.json");
});

parser.registerPreprocessor(PreprocessorTest::preprocessor);

Assertions.assertDoesNotThrow(() -> parser.extract("com/lumiomedical/vault/parser/simple.old_style.json"));

Definitions definitions = parser.extract("com/lumiomedical/vault/parser/simple.old_style.json");

ParserTest.makeAssertions(definitions);
}

/**
*
* @param node
* @return
* @throws VaultParserException
*/
private static ObjectNode preprocessor(ObjectNode node) throws VaultParserException
{
if (!node.has("services") || !node.get("services").isArray())
return node;

var objServices = Json.newObject();

node.get("services").forEach(rethrower(serviceNode -> {

if (!serviceNode.has("identifier"))
throw new VaultParserException("A service node declared in an old-style service array has no identifier field.");

objServices.set(
serviceNode.get("identifier").asText(),
serviceNode
);
}));

node.set("services", objServices);

return node;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"variables": {
"provider.integer.value": 1234
},
"services": [
{
"identifier": "provider.integer",
"class": "com.lumiomedical.vault.service.IntegerProvider",
"constructor": [
"##provider.integer.value##"
]
}
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"imports": [
"com/lumiomedical/vault/parser/provider.string.json",
"com/lumiomedical/vault/parser/provider.boolean.json",
"com/lumiomedical/vault/parser/provider.integer.old_style.json"
],
"variables": {
"provider.integer.value": 2345,
"provider.double.value": 12.34,
"provider.string.base_value": "SomeString",
"provider.string.value": "##provider.string.base_value##"
},
"services": [
{
"identifier": "alias.string",
"alias": "provider.string"
},
{
"identifier": "provider.boolean.base",
"class": "com.lumiomedical.vault.service.BooleanProvider",
"constructor": [ false ]
},
{
"identifier": "provider.double",
"class": "com.lumiomedical.vault.service.DoubleProvider",
"constructor": [
"##provider.double.value##"
],
"invocations": [
["provide"]
]
},
{
"identifier": "provider.string",
"class": "com.lumiomedical.vault.service.StringProvider",
"method": "build",
"arguments": [
"##provider.string.value##"
]
},
{
"identifier": "provider.boolean",
"class": "com.lumiomedical.vault.service.ServiceProvider",
"arguments": [
"@provider.boolean.base"
]
}
]
}

0 comments on commit 79a1201

Please sign in to comment.