Skip to content

Commit

Permalink
feat(core): support defining additional validation rule directories...
Browse files Browse the repository at this point in the history
...per plugin
  • Loading branch information
cmark committed Sep 27, 2023
1 parent 1475bd8 commit 05c9df8
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@
import static com.google.common.collect.Sets.newHashSet;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

Expand All @@ -42,6 +40,7 @@
import com.b2international.snowowl.core.setup.Environment;
import com.b2international.snowowl.core.setup.Plugin;
import com.b2international.snowowl.core.validation.ValidationRequests;
import com.b2international.snowowl.core.validation.ValidationRuleDirectoryProvider;
import com.b2international.snowowl.core.validation.eval.GroovyScriptValidationRuleEvaluator;
import com.b2international.snowowl.core.validation.eval.ValidationRuleEvaluator;
import com.b2international.snowowl.core.validation.issue.ValidationIssue;
Expand Down Expand Up @@ -73,6 +72,16 @@ public void addConfigurations(ConfigurationRegistry registry) {
@Override
public void preRun(SnowOwlConfiguration configuration, Environment env) throws Exception {
if (env.isServer()) {
final List<Path> validationDirectories = new ArrayList<>();
// default directory is the server configuration dir
validationDirectories.add(env.getConfigPath());
// support additional directories to be appended by plug-ins during the init method via the ValidationRuleDirectoryProvider
env.plugins().getPlugins().forEach(plugin -> {
if (plugin instanceof ValidationRuleDirectoryProvider vrdp) {
validationDirectories.addAll(vrdp.getDirectories());
}
});

final ObjectMapper mapper = env.service(ObjectMapper.class);
final Index validationIndex = Indexes.createIndex(
VALIDATIONS_INDEX,
Expand All @@ -85,7 +94,7 @@ public void preRun(SnowOwlConfiguration configuration, Environment env) throws E
env.services().registerService(ValidationRepository.class, repository);

// register always available validation rule evaluators
ValidationRuleEvaluator.Registry.register(new GroovyScriptValidationRuleEvaluator(env.getConfigPath()));
ValidationRuleEvaluator.Registry.register(new GroovyScriptValidationRuleEvaluator(validationDirectories));

// initialize validation thread pool
final ValidationConfiguration validationConfig = configuration.getModuleConfig(ValidationConfiguration.class);
Expand All @@ -98,7 +107,7 @@ public void preRun(SnowOwlConfiguration configuration, Environment env) throws E
env.services().registerService(ValidationThreadPool.class, new ValidationThreadPool(numberOfValidationThreads, maxConcurrentExpensiveJobs, maxConcurrentNormalJobs));
env.services().registerService(ValidationIssueDetailExtensionProvider.class, new ValidationIssueDetailExtensionProvider(env.service(ClassPathScanner.class)));

final List<File> listOfFiles = Arrays.asList(env.getConfigPath().toFile().listFiles());
final List<File> listOfFiles = validationDirectories.stream().flatMap(path -> Arrays.asList(path.toFile().listFiles()).stream()).toList();
final Set<File> validationRuleFiles = Sets.newHashSet();
final Pattern validationFilenamePattern = Pattern.compile("(validation-rules)-(\\w+).(json)");
for (File file : listOfFiles) {
Expand Down Expand Up @@ -142,9 +151,9 @@ public void preRun(SnowOwlConfiguration configuration, Environment env) throws E
.build())
.getHits());
writer.removeAll(ImmutableMap.<Class<?>, Set<String>>of(
ValidationRule.class, rulesToDelete,
ValidationIssue.class, issuesToDelete
));
ValidationRule.class, rulesToDelete,
ValidationIssue.class, issuesToDelete
));
}

writer.commit();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright 2023 B2i Healthcare Pte Ltd, http://b2i.sg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.b2international.snowowl.core.validation;

import java.nio.file.Path;
import java.util.List;

/**
* @since 9.0
*/
public interface ValidationRuleDirectoryProvider {

/**
* @return additional directories to be registered where validation rule JSON descriptors and scripts can be parsed and registered.
*/
List<Path> getDirectories();

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2017-2020 B2i Healthcare Pte Ltd, http://b2i.sg
* Copyright 2017-2023 B2i Healthcare Pte Ltd, http://b2i.sg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
Expand All @@ -37,25 +38,30 @@
*/
public final class GroovyScriptValidationRuleEvaluator implements ValidationRuleEvaluator {

private Path validationResourcesDirectory;
private List<Path> validationResourcesDirectories;

public GroovyScriptValidationRuleEvaluator(Path validationResourcesDirectory) {
this.validationResourcesDirectory = validationResourcesDirectory;
public GroovyScriptValidationRuleEvaluator(List<Path> validationResourcesDirectories) {
this.validationResourcesDirectories = validationResourcesDirectories;
}

@VisibleForTesting
public void setValidationResourcesDirectory(Path validationResourcesDirectory) {
this.validationResourcesDirectory = validationResourcesDirectory;
public void setValidationResourcesDirectory(List<Path> validationResourcesDirectories) {
this.validationResourcesDirectories = validationResourcesDirectories;
}

@Override
public List<?> eval(BranchContext context, ValidationRule rule, Map<String, Object> filterParams) throws IOException {
final Path validationRuleFilePath = validationResourcesDirectory.resolve(rule.getImplementation());
final Path validationRuleFilePath = validationResourcesDirectories.stream()
.map(dir -> dir.resolve(rule.getImplementation()))
.filter(Files::exists)
.findFirst()
.orElseThrow(() -> new NoSuchFileException(String.format("Validation rule implementation file '%s' could not be found.", rule.getImplementation())));

try (final Stream<String> lines = Files.lines(validationRuleFilePath)) {

final String script = lines.collect(Collectors.joining(System.getProperty("line.separator")));

final Builder<String, Object> paramsBuilder = ImmutableMap.<String, Object>builder().put("resourcesDir", validationResourcesDirectory);
final Builder<String, Object> paramsBuilder = ImmutableMap.builder();

if (filterParams != null && !filterParams.isEmpty()) {
paramsBuilder.putAll(filterParams);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2018-2019 B2i Healthcare Pte Ltd, http://b2i.sg
* Copyright 2018-2023 B2i Healthcare Pte Ltd, http://b2i.sg
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@
package com.b2international.snowowl.validation.snomed;

import java.nio.file.Path;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.runner.RunWith;
Expand All @@ -40,7 +41,7 @@ public class AllGenericValidationTests {
public static void init() {
ValidationRuleEvaluator.Registry.register(new SnomedQueryValidationRuleEvaluator());
final Path resourcesDir = PlatformUtil.toAbsoluteBundlePath(BaseGenericValidationRuleTest.class.getClassLoader().getResource("src/main/resources"));
ValidationRuleEvaluator.Registry.register(new GroovyScriptValidationRuleEvaluator(resourcesDir));
ValidationRuleEvaluator.Registry.register(new GroovyScriptValidationRuleEvaluator(List.of(resourcesDir)));
TerminologyRegistry.INSTANCE.register(new SnomedPlugin());
}

Expand Down

0 comments on commit 05c9df8

Please sign in to comment.