Skip to content
Snippets Groups Projects
Commit 85242355 authored by Jonas Blatt's avatar Jonas Blatt :ant:
Browse files

Merge branch 'feature/syncWithCamundaEngine' into 'develop'

Add camunda engine synchronisation of dmn definitions for continuous integration

See merge request jonasblatt/ma-jonasblatt-dmn-verifier!43
parents 592110e6 6092c846
No related branches found
No related tags found
No related merge requests found
Showing
with 302 additions and 27 deletions
......@@ -42,10 +42,6 @@
<version>${version.camunda}</version>
</dependency>
<!-- Quarkus -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jsonb</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
......
......@@ -60,9 +60,7 @@ public class SubsumptionVerifier extends AbstractVerifier {
vreFactory.addVerificationFix(SHOW_RULES);
vreFactory.addToEntry(
VerificationClassification.WARNING,
templateDecision(inColumns.get(0).getDmnDecision())
+ getMessageText(
currentRules, currentRootSubsumptionElements, differentConclusions));
getMessageText(currentRules, currentRootSubsumptionElements, differentConclusions));
}
} else {
// get all input values from the current column, and filter with the prev. iteration
......
......@@ -2,10 +2,15 @@ package de.unikoblenz.fgbks.dmn.frontend;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.json.bind.annotation.JsonbProperty;
@SessionScoped
public class DmnBean implements Serializable {
@JsonbProperty("camundaUrl")
protected String camundaUrl = "";
@JsonbProperty("dmnXml")
protected String dmnXml;
public String getDmnXml() {
......@@ -15,4 +20,12 @@ public class DmnBean implements Serializable {
public void setDmnXml(String dmnXml) {
this.dmnXml = dmnXml;
}
public String getCamundaUrl() {
return camundaUrl;
}
public void setCamundaUrl(String camundaUrl) {
this.camundaUrl = camundaUrl;
}
}
......@@ -16,19 +16,25 @@ public class DmnSessionApi {
DmnBean dmnBean;
@GET
@Path("/getdmn")
@Produces(MediaType.TEXT_XML)
@Produces(MediaType.APPLICATION_JSON)
public Response getSessionDmn() {
if (dmnBean.getDmnXml() == null) {
return Response.noContent().build();
}
return Response.ok(dmnBean.getDmnXml()).build();
return Response.ok(dmnBean).build();
}
@POST
@Path("/setdmn")
@Path("/setDmn")
@Consumes(MediaType.TEXT_XML)
public void setSessionDmn(String dmnXml) {
dmnBean.setDmnXml(dmnXml);
}
@POST
@Path("/setCamundaUrl")
@Consumes(MediaType.TEXT_PLAIN)
public void setCamundaUrl(String camundaUrl) {
dmnBean.setCamundaUrl(camundaUrl);
}
}
dmnverifierfrontend/src/main/resources/META-INF/resources/css/img/camundaConnect.png

17.2 KiB

......@@ -14,6 +14,10 @@ h1 {
color: #0b3004;
}
button {
background-color: white;
}
h2 {
margin: 10px;
}
......@@ -84,6 +88,7 @@ span.select2 {
.clickable {
box-shadow: 2px 2px 3px 2px rgba(0, 0, 0, .3);
cursor: pointer;
}
.clickable:hover {
......@@ -101,12 +106,13 @@ span.select2 {
}
.dmn-top {
height: 60px;
padding-left: 6px;
padding-top: 6px;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
margin-bottom: 5px;
}
.dmn-top-item {
......@@ -124,6 +130,7 @@ span.select2 {
display: block;
background-size: cover;
background-position: center;
cursor: pointer;
}
.dmn-upload {
......@@ -154,6 +161,30 @@ span.select2 {
width: 50px;
}
.dmn-camunda-api {
flex-grow: 1;
}
.dmn-camunda-api > label {
background-image: url("img/camundaConnect.png");
width: 50px;
}
.dmn-camunda-api > label > a {
display: inline-block;
width: 100%;
height: 100%;
}
/** Modal */
.modal-element {
width: 100%;
margin: 5px;
min-height: 25px;
padding: 5px;
font: 12pt Calibri;
}
/** Verifier configuration */
#dmn-verifier-header {
......@@ -167,14 +198,12 @@ span.select2 {
#dmn-button-verify {
flex-grow: 1;
max-width: 90px;
background: white;
border-radius: 2px;
}
#dmn-button-reload-verifier {
flex-grow: 1;
max-width: 120px;
background: white;
border-radius: 2px;
}
......@@ -182,7 +211,6 @@ span.select2 {
margin: 8px 12px;
color: #0b3004;
min-height: 35px;
cursor: pointer;
font-family: 'Open Sans', sans-serif;
font-size: 13px;
}
......@@ -268,5 +296,4 @@ span.select2 {
height: 25px;
min-width: 100px;
margin: 2px 2px 2px 10px;
background: white;
}
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_1kjh9a2" name="DRD" namespace="http://camunda.org/schema/1.0/dmn">
<decision id="Decision_13nychf" name="Decision 1">
<definitions xmlns="http://www.omg.org/spec/DMN/20151101/dmn.xsd" xmlns:biodi="http://bpmn.io/schema/dmn/biodi/1.0" id="Definitions_genid1" name="DRD" namespace="http://camunda.org/schema/1.0/dmn">
<decision id="Decision_genid2" name="Decision 1">
<extensionElements>
<biodi:bounds x="120" y="145" width="180" height="80" />
</extensionElements>
......
......@@ -14,7 +14,8 @@
<link href="https://unpkg.com/dmn-js@7.0.1/dist/assets/dmn-js-literal-expression.css"
rel="stylesheet">
<link href="https://unpkg.com/dmn-js@7.0.1/dist/assets/dmn-font/css/dmn.css" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.css"
rel="stylesheet"/>
<link href="assets/css/select2.min.css" rel="stylesheet"/>
<link href="css/stylesheets.css" rel="stylesheet" type="text/css"/>
......@@ -28,15 +29,20 @@
</label>
<input id="dmn-file-upload" type="file"/>
</div>
<div class="dmn-top-item dmn-download">
<label class="clickable" for="dmn-file-download" title="Download current dmn">
</label>
<input id="dmn-file-download" type="button"/>
</div>
<div class="dmn-top-item dmn-empty-file">
<label class="clickable" for="dmn-file-empty" title="Create empty dmn">
</label>
<input id="dmn-file-empty" type="button"/>
</div>
<div class="dmn-top-item dmn-download">
<label class="clickable" for="dmn-file-download" title="Download current dmn">
<div class="dmn-top-item dmn-camunda-api">
<label class="clickable" for="dmn-camunda-api" title="Connect to Camunda Engine">
<a href="#modal-camunda-api" id="dmn-camunda-api" rel="modal:open"></a>
</label>
<input id="dmn-file-download" type="button"/>
</div>
<div class="dmn-top-item">
<h1>Verification for Decision Modeling Notation</h1>
......@@ -53,14 +59,22 @@
</div>
<div id="root-dmn-verifier"></div>
</div>
<!-- modal for camunda engine -->
<div class="modal" id="modal-camunda-api">
<div id="camunda-api-root"></div>
</div>
<!-- load jquery -->
<script src="https://unpkg.com/jquery@3.4.1/dist/jquery.js" type="text/javascript"></script>
<script src="assets/js/select2.full.min.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-modal/0.9.1/jquery.modal.min.js"></script>
<!-- load dmn modeler -->
<script src="https://unpkg.com/dmn-js@7.0.1/dist/dmn-modeler.development.js"></script>
<script src="js/dmnUpDownload.js" type="text/javascript"></script>
<script src="js/dmnViewer.js" type="text/javascript"></script>
<script src="js/dmnVerifier.js" type="text/javascript"></script>
<script src="js/dmnCamundaApi.js" type="text/javascript"></script>
</body>
</html>
const engineUrl = 'engine-rest/';
let camundaEngineUrl = '';
let connectionSuccess = false;
let $camundaApiRoot = $('#camunda-api-root');
let $textCamundaUrl = $(`
<input class="modal-element" type="text" size="60">
`);
$textCamundaUrl.val('localhost');
let $buttonConnectCamundaUrl = $(`
<button class="clickable modal-element" size="60" id="camunda-connect"
onclick="connectCamunda()">Connect</button>
`);
let $selectCamundaDecisions = $(
`<select class="clickable modal-element" name="decisions"
id="select-camunda-decisions"
onchange="loadCamundaDecisionXml(this)">
`);
let $buttonDeployDmn = $(`
<button class="clickable modal-element" size="60" id="camunda-connect"
onclick="deployDmn()">Deploy DMN</button>
`);
let $camundaApiContainer = $(`<div id="camunda-api-container">`);
// register Button action
$(document).ready(function () {
clearCamundaApiRoot();
});
function clearCamundaApiRoot() {
$camundaApiRoot.empty();
$camundaApiRoot.append($(`<h2>Camunda DMN Deployment</h2>`));
$camundaApiRoot.append($camundaApiContainer);
loadCamundaSessionParams();
}
function refreshParams() {
$textCamundaUrl.val(camundaEngineUrl);
$camundaApiContainer.empty();
if (connectionSuccess) {
$camundaApiContainer.append($selectCamundaDecisions);
$camundaApiContainer.append($buttonDeployDmn);
} else {
$camundaApiContainer.append($textCamundaUrl);
$camundaApiContainer.append($buttonConnectCamundaUrl);
}
}
function connectCamunda() {
camundaEngineUrl = $textCamundaUrl.val();
if (!camundaEngineUrl.endsWith('/')) {
camundaEngineUrl += '/';
}
if (!camundaEngineUrl.startsWith('http://')) {
camundaEngineUrl = 'http://' + camundaEngineUrl;
}
$textCamundaUrl.val(camundaEngineUrl);
requestOptionsCamundaDecisions();
}
function deployDmn() {
let dmnXml = exportDiagram();
if (dmnXml) {
if (confirm("Do you really want to deploy this dmn?")) {
var fileStringArray = [dmnXml];
var fileName = "file.dmn";
var blobAttrs = {type: "xml"};
var file = new File(fileStringArray, fileName, blobAttrs);
var formData = new FormData();
formData.append("deployment-name", "test");
formData.append("enable-duplicate-filtering", "true");
formData.append("deployment-source", "process application");
formData.append("data", file, file.name);
$.ajax({
url: camundaEngineUrl + engineUrl + "deployment/create",
type: "POST",
data: formData,
enctype: 'multipart/form-data',
async: true,
crossDomain: true,
processData: false,
contentType: false,
cache: false,
timeout: 0,
success: function (data) {
$.modal.close();
requestOptionsCamundaDecisions();
},
error: function (e) {
alert("There was a error while deploying the dmn.");
}
});
}
}
}
function saveCamundaUrl() {
$.ajax({
timeout: 1000,
url: "/dmn/setCamundaUrl",
type: 'POST',
contentType: 'text/plain',
data: $textCamundaUrl.val(),
error: function (err) {
// nothing
console.log(err);
}
});
}
function loadCamundaSessionParams() {
$.ajax({
timeout: 1000,
url: "/dmn",
type: 'GET',
contentType: 'application/json',
error: function (err) {
camundaEngineUrl = '';
connectionSuccess = false;
refreshParams();
},
success: function (data) {
if (data !== undefined && data.camundaUrl !== undefined) {
camundaEngineUrl = data.camundaUrl;
} else {
camundaEngineUrl = '';
}
refreshParams();
}
});
}
function requestOptionsCamundaDecisions() {
$selectCamundaDecisions.empty();
$.ajax({
timeout: 1000,
url: camundaEngineUrl + engineUrl
+ 'decision-definition?latestVersion=true',
type: 'GET',
contentType: 'application/json',
error: function (err) {
connectionSuccess = false;
alert(
"Error: No connection to the camunda engine established. Check URL or CORS options.");
refreshParams();
},
success: function (data) {
connectionSuccess = true;
renderDecisionsOptions(data);
saveCamundaUrl();
refreshParams();
}
});
}
function renderDecisionsOptions(decisions) {
$selectCamundaDecisions.empty();
$selectCamundaDecisions.append($(`
<option value="null" selected>Select a definition</option>
`));
for (let i = 0; i < decisions.length; i++) {
let decision = decisions[i];
$selectCamundaDecisions.append($(`
<option value="${decision.key}">${decision.name} (Version: ${decision.version})</option>
`));
}
}
function loadCamundaDecisionXml(decisionSelect) {
if (decisionSelect.value !== 'null') {
if (confirm(
'Do you really want to load the dmn "'
+ $("#select-camunda-decisions option:selected").text()
+ '"?')) {
$.ajax({
timeout: 1000,
url: camundaEngineUrl + engineUrl + 'decision-definition/key/'
+ decisionSelect.value
+ '/xml/',
type: 'GET',
error: function (err) {
console.log("error", err);
connectionSuccess = false;
refreshParams();
alert(err);
},
success: function (data) {
openDiagram(data.dmnXml);
refreshParams();
$.modal.close();
}
});
}
}
}
......@@ -21,8 +21,12 @@ function loadEmptyFile() {
$.ajax({
url: 'dmn/emptyDMN.dmn',
type: 'GET',
cache: false,
contentType: 'text/xml',
success: function (data) {
// TODO, replace definition ID
data = data.replace("genid1", generateId(8))
.replace("genid2", generateId(8));
openDiagram(data);
}
});
......@@ -48,9 +52,9 @@ let oSerializer = new XMLSerializer();
function loadSessionDmn() {
$.ajax({
timeout: 1000,
url: "/dmn/getdmn",
url: "/dmn",
type: 'GET',
contentType: 'text/xml',
contentType: 'application/json',
error: function (err) {
// nothing
console.log(">-->--> loading session dmn failed. <--<--<");
......@@ -58,8 +62,13 @@ function loadSessionDmn() {
loadEmptyFile();
},
success: function (data) {
let sXML = oSerializer.serializeToString(data);
openDiagram(sXML);
if (data !== undefined && data.dmnXml !== undefined) {
// let sXML = oSerializer.serializeToString(data.dmnXml);
let sXML = data.dmnXml;
openDiagram(sXML);
} else {
loadEmptyFile();
}
}
});
}
......@@ -68,7 +77,7 @@ function saveSessionDmn() {
let dmnXml = exportDiagram();
$.ajax({
timeout: 1000,
url: "/dmn/setdmn",
url: "/dmn/setDmn",
type: 'POST',
contentType: 'text/xml',
data: dmnXml,
......@@ -78,3 +87,13 @@ function saveSessionDmn() {
}
});
}
function generateId(length) {
var result = '';
var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
}
......@@ -37,6 +37,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy</artifactId>
</dependency>
<dependency>
<artifactId>quarkus-resteasy-jsonb</artifactId>
<groupId>io.quarkus</groupId>
</dependency>
</dependencies>
<modules>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment