Skip to content

Commit

Permalink
[incubator-kie-kogito-runtimes#2608] Generating one definitions json …
Browse files Browse the repository at this point in the history
…for each DMN model (#3424)

* [incubator-kie-kogito-runtimes#2608] Generating one definitions json for each DMN model

* [incubator-kie-kogito-runtimes#2608] Fix as per PR comment. Add tests.

* [incubator-kie-kogito-runtimes#2608] Fix tests.

* [incubator-kie-kogito-runtimes#2608] Fix tests.

* [incubator-kie-kogito-runtimes#2608] Fix formatting.

---------

Co-authored-by: Gabriele-Cardosi <gabriele.cardosi@ibm.com>
  • Loading branch information
gitgabrio and Gabriele-Cardosi authored Mar 8, 2024
1 parent b896f93 commit f04c2a3
Show file tree
Hide file tree
Showing 11 changed files with 436 additions and 30 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.kie.kogito.codegen.decision;

import org.kie.dmn.api.core.DMNModel;

public class CodegenUtils {

private CodegenUtils() {
}

public static String getDefinitionsFileFromModel(DMNModel dmnModel) {
String modelName = geNameForDefinitionsFile(dmnModel);
return modelName.replace(" ", "_").replace(".dmn", ".json");
}

static String geNameForDefinitionsFile(DMNModel dmnModel) {
if (dmnModel.getResource() != null && dmnModel.getResource().getSourcePath() != null) {
String resourcePath = dmnModel.getResource().getSourcePath().replace('\\', '/');
return resourcePath.contains("/") ? resourcePath.substring(resourcePath.lastIndexOf('/') + 1) : resourcePath;
} else {
return dmnModel.getName() + ".dmn";
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
Expand Down Expand Up @@ -66,6 +65,7 @@
import com.fasterxml.jackson.databind.ObjectMapper;

import static java.util.stream.Collectors.toList;
import static org.kie.kogito.codegen.decision.CodegenUtils.getDefinitionsFileFromModel;

public class DecisionCodegen extends AbstractGenerator {

Expand Down Expand Up @@ -134,22 +134,11 @@ private void generateAndStoreRestResources() {
List<DecisionRestResourceGenerator> rgs = new ArrayList<>(); // REST resources
List<DMNModel> models = resources.stream().map(DMNResource::getDmnModel).collect(Collectors.toList());

DMNOASResult oasResult = null;
try {
Comparator<DMNModel> nsNameComparator = Comparator.comparing(DMNModel::getNamespace).thenComparing(DMNModel::getName);
List<DMNModel> orderedModels = new ArrayList<>(models);
Collections.sort(orderedModels, nsNameComparator);
oasResult = DMNOASGeneratorFactory.generator(orderedModels).build();
String jsonContent = new ObjectMapper().writeValueAsString(oasResult.getJsonSchemaNode());
storeFile(GeneratedFileType.STATIC_HTTP_RESOURCE, "dmnDefinitions.json", jsonContent);
} catch (Exception e) {
LOGGER.error("Error while trying to generate OpenAPI specification for the DMN models", e);
}

for (DMNModel model : models) {
if (model.getName() == null || model.getName().isEmpty()) {
throw new RuntimeException("Model name should not be empty");
}
DMNOASResult oasResult = generateAndStoreDefinitionsJson(model);

boolean stronglyTypedEnabled = Optional.ofNullable(context())
.flatMap(c -> c.getApplicationProperty(STRONGLY_TYPED_CONFIGURATION_KEY))
Expand Down Expand Up @@ -198,6 +187,19 @@ private void generateAndStoreRestResources() {
}
}

private DMNOASResult generateAndStoreDefinitionsJson(DMNModel dmnModel) {
DMNOASResult toReturn = null;
try {
toReturn = DMNOASGeneratorFactory.generator(Collections.singleton(dmnModel)).build();
String jsonContent = new ObjectMapper().writeValueAsString(toReturn.getJsonSchemaNode());
final String DMN_DEFINITIONS_JSON = getDefinitionsFileFromModel(dmnModel);
storeFile(GeneratedFileType.STATIC_HTTP_RESOURCE, DMN_DEFINITIONS_JSON, jsonContent);
} catch (Exception e) {
LOGGER.error("Error while trying to generate OpenAPI specification for the DMN models", e);
}
return toReturn;
}

private void generateAndStoreDecisionModelResourcesProvider() {
final DecisionModelResourcesProviderGenerator generator = new DecisionModelResourcesProviderGenerator(context(),
applicationCanonicalName(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@

import static com.github.javaparser.StaticJavaParser.parseStatement;
import static java.util.function.Predicate.not;
import static org.kie.kogito.codegen.decision.CodegenUtils.getDefinitionsFileFromModel;

public class DecisionRestResourceGenerator {

Expand Down Expand Up @@ -203,7 +204,7 @@ private void processOASAnn(MethodDeclaration dmnMethod, DecisionService ds) {
inputRef = withOASResult.getNamingPolicy().getRef(identifyInputSet);
outputRef = withOASResult.getNamingPolicy().getRef(identifyOutputSet);
}
final String DMN_DEFINITIONS_JSON = "/dmnDefinitions.json";
final String DMN_DEFINITIONS_JSON = "/" + getDefinitionsFileFromModel(dmnModel);
// MP / Quarkus
final String Q_CTX_PATH = context.getApplicationProperty("quarkus.http.root-path").filter(not("/"::equals)).orElse("");
processAnnForRef(dmnMethod,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.kie.kogito.codegen.decision;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.util.Collections;

import org.drools.io.FileSystemResource;
import org.drools.util.FileUtils;
import org.junit.jupiter.api.Test;
import org.kie.api.io.Resource;
import org.kie.dmn.api.core.DMNModel;
import org.kie.dmn.api.core.DMNRuntime;
import org.kie.dmn.core.internal.utils.DMNRuntimeBuilder;
import org.kie.kogito.dmn.DMNKogito;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

class CodegenUtilsTest {

@Test
void getDefinitionsFileFromModelWithSpace() {
File dmnFile = FileUtils.getFile("Traffic Violation.dmn");
assertNotNull(dmnFile);
assertTrue(dmnFile.exists());
Resource dmnResource = new FileSystemResource(dmnFile, StandardCharsets.UTF_8.name());

DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults()
.setRootClassLoader(Thread.currentThread().getContextClassLoader())
.buildConfiguration()
.fromResources(Collections.singleton(dmnResource))
.getOrElseThrow(e -> new RuntimeException("Error compiling DMN model(s)", e));
assertThat(dmnRuntime.getModels()).hasSize(1);
final DMNModel dmnModel = dmnRuntime.getModel("https://github.com/kiegroup/drools/kie-dmn/_A4BCA8B8-CF08-433F-93B2-A2598F19ECFF", "Traffic Violation Model Name");
assertNotNull(dmnModel);
String expected = "Traffic_Violation.json";
assertEquals(expected, CodegenUtils.getDefinitionsFileFromModel(dmnModel));
}

@Test
void geNameForDefinitionsFileWithSourcePath() {
File dmnFile = FileUtils.getFile("Traffic Violation.dmn");
assertNotNull(dmnFile);
assertTrue(dmnFile.exists());
Resource dmnResource = new FileSystemResource(dmnFile, StandardCharsets.UTF_8.name());
DMNRuntime dmnRuntime = DMNRuntimeBuilder.fromDefaults()
.setRootClassLoader(Thread.currentThread().getContextClassLoader())
.buildConfiguration()
.fromResources(Collections.singleton(dmnResource))
.getOrElseThrow(e -> new RuntimeException("Error compiling DMN model(s)", e));
assertThat(dmnRuntime.getModels()).hasSize(1);
final DMNModel dmnModel = dmnRuntime.getModel("https://github.com/kiegroup/drools/kie-dmn/_A4BCA8B8-CF08-433F-93B2-A2598F19ECFF", "Traffic Violation Model Name");
assertNotNull(dmnModel);
String expected = "Traffic Violation.dmn";
assertEquals(expected, CodegenUtils.geNameForDefinitionsFile(dmnModel));
}

@Test
void geNameForDefinitionsFileWithoutSourcePath() throws FileNotFoundException {
File dmnFile = FileUtils.getFile("Traffic Violation.dmn");
assertNotNull(dmnFile);
assertTrue(dmnFile.exists());
DMNRuntime dmnRuntime = DMNKogito.createGenericDMNRuntime(new FileReader(dmnFile));
assertNotNull(dmnRuntime);
assertThat(dmnRuntime.getModels()).hasSize(1);
final DMNModel dmnModel = dmnRuntime.getModel("https://github.com/kiegroup/drools/kie-dmn/_A4BCA8B8-CF08-433F-93B2-A2598F19ECFF", "Traffic Violation Model Name");
assertNotNull(dmnModel);
String expected = "Traffic Violation Model Name.dmn";
assertEquals(expected, CodegenUtils.geNameForDefinitionsFile(dmnModel));
}
}
Loading

0 comments on commit f04c2a3

Please sign in to comment.