Skip to content

Commit 940fc08

Browse files
authored
Merge pull request #73 from envite-consulting/lucalimbach/improve-event-connection
Enhance event search
2 parents 0169ad4 + 76cf26c commit 940fc08

10 files changed

Lines changed: 191 additions & 36 deletions

File tree

README.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,22 @@ To activate either mode please navigate to the frontend folder via `cd frontend`
1313

1414
Web mode: The default user is `admin` and the default password is `admin`.
1515

16-
### Generating JWT keys (web mode only)
16+
## Generating JWT keys (web mode only)
1717

1818
To generate the keys necessary for authentication via JWT please run the following script once:
1919
```
2020
./backend/generate-keys.sh
2121
```
2222

23+
## Database and Fuzzy Match
24+
ProA uses fuzzy match so that the BPMN labels can be matched with some degree of tolerance, e.g. ignoring typos.
25+
To this end, postgres levenshtein function is used, which needs to be activated by ececuting the following:
26+
27+
```CREATE EXTENSION fuzzystrmatch;```
28+
29+
Furthermore, in Azure before executing the above statement, the extension needs to be activated via: DB >> Settings >> Server parameters >> azure.extensions >> fuzzystrmatch;
30+
31+
2332
## The Entire Application
2433

2534
In order to build an uber jar, which also contains the frontend, run the following in the root:

backend/src/main/java/de/envite/proa/repository/datastore/DataStoreDao.java

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
import de.envite.proa.repository.tables.DataStoreTable;
44
import de.envite.proa.repository.tables.ProjectVersionTable;
5+
import de.envite.proa.util.SearchLabelBuilder;
56
import jakarta.enterprise.context.ApplicationScoped;
67
import jakarta.inject.Inject;
78
import jakarta.persistence.EntityManager;
89
import jakarta.transaction.Transactional;
10+
import org.eclipse.microprofile.config.inject.ConfigProperty;
911

1012
import java.util.List;
1113

1214
@ApplicationScoped
1315
public class DataStoreDao {
1416

17+
@ConfigProperty(name = "quarkus.datasource.db-kind")
18+
String dbKind;
19+
1520
private EntityManager em;
1621

1722
@Inject
@@ -34,11 +39,28 @@ public List<DataStoreTable> getDataStores(ProjectVersionTable projectVersionTabl
3439

3540
@Transactional
3641
public DataStoreTable getDataStoreForLabel(String label, ProjectVersionTable projectVersionTable) {
37-
return em //
38-
.createQuery("SELECT d FROM DataStoreTable d WHERE d.label = :label AND d.project = :project",
39-
DataStoreTable.class)
40-
.setParameter("label", label)//
41-
.setParameter("project", projectVersionTable)//
42-
.getSingleResult();
42+
43+
String searchLabel = SearchLabelBuilder.buildSearchLabel(label);
44+
45+
if ("postgresql".equals(dbKind)) {
46+
return em.createQuery(
47+
"SELECT d FROM DataStoreTable d " +
48+
"WHERE d.project = :project " +
49+
"AND ( d.searchLabel = :searchLabel " +
50+
"OR function('levenshtein', d.searchLabel, :searchLabel) <= 4 )",
51+
DataStoreTable.class)
52+
.setParameter("searchLabel", searchLabel)//
53+
.setParameter("project", projectVersionTable)//
54+
.getSingleResult();
55+
} else {
56+
return em.createQuery(
57+
"SELECT d FROM DataStoreTable d " +
58+
"WHERE d.project = :project " +
59+
"AND d.searchLabel = :searchLabel ",
60+
DataStoreTable.class)
61+
.setParameter("searchLabel", searchLabel)//
62+
.setParameter("project", projectVersionTable)//
63+
.getSingleResult();
64+
}
4365
}
4466
}

backend/src/main/java/de/envite/proa/repository/processmodel/CallActivityDao.java

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,21 @@
33
import de.envite.proa.repository.tables.CallActivityTable;
44
import de.envite.proa.repository.tables.ProcessModelTable;
55
import de.envite.proa.repository.tables.ProjectVersionTable;
6+
import de.envite.proa.util.SearchLabelBuilder;
67
import jakarta.enterprise.context.RequestScoped;
78
import jakarta.inject.Inject;
89
import jakarta.persistence.EntityManager;
910
import jakarta.transaction.Transactional;
11+
import org.eclipse.microprofile.config.inject.ConfigProperty;
1012

1113
import java.util.List;
1214

1315
@RequestScoped
1416
public class CallActivityDao {
1517

18+
@ConfigProperty(name = "quarkus.datasource.db-kind")
19+
String dbKind;
20+
1621
private final EntityManager em;
1722

1823
@Inject
@@ -26,13 +31,30 @@ public void persist(CallActivityTable table) {
2631
}
2732

2833
@Transactional
29-
public List<CallActivityTable> getCallActivitiesForName(String name, ProjectVersionTable project) {
30-
return em //
31-
.createQuery("SELECT c FROM CallActivityTable c WHERE c.label = :label AND c.project = :project",
32-
CallActivityTable.class)
33-
.setParameter("label", name)//
34-
.setParameter("project", project)//
35-
.getResultList();
34+
public List<CallActivityTable> getCallActivitiesForName(String label, ProjectVersionTable projectVersionTable) {
35+
36+
String searchLabel = SearchLabelBuilder.buildSearchLabel(label);
37+
38+
if ("postgresql".equals(dbKind)) {
39+
return em.createQuery(
40+
"SELECT c FROM CallActivityTable c " +
41+
"WHERE c.project = :project " +
42+
"AND ( c.searchLabel = :searchLabel " +
43+
"OR function('levenshtein', c.searchLabel, :searchLabel) <= 4 )",
44+
CallActivityTable.class)
45+
.setParameter("searchLabel", searchLabel)//
46+
.setParameter("project", projectVersionTable)//
47+
.getResultList();
48+
} else {
49+
return em.createQuery(
50+
"SELECT c FROM CallActivityTable c " +
51+
"WHERE c.project = :project " +
52+
"AND c.searchLabel = :searchLabel ",
53+
CallActivityTable.class)
54+
.setParameter("searchLabel", searchLabel)//
55+
.setParameter("project", projectVersionTable)//
56+
.getResultList();
57+
}
3658
}
3759

3860
@Transactional

backend/src/main/java/de/envite/proa/repository/processmodel/ProcessEventDao.java

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,24 @@
11
package de.envite.proa.repository.processmodel;
22

3+
import java.util.List;
4+
35
import de.envite.proa.entities.process.EventType;
46
import de.envite.proa.repository.tables.ProcessEventTable;
57
import de.envite.proa.repository.tables.ProcessModelTable;
68
import de.envite.proa.repository.tables.ProjectVersionTable;
9+
import de.envite.proa.util.SearchLabelBuilder;
710
import jakarta.enterprise.context.RequestScoped;
811
import jakarta.inject.Inject;
912
import jakarta.persistence.EntityManager;
1013
import jakarta.transaction.Transactional;
11-
12-
import java.util.List;
14+
import org.eclipse.microprofile.config.inject.ConfigProperty;
1315

1416
@RequestScoped
1517
public class ProcessEventDao {
1618

19+
@ConfigProperty(name = "quarkus.datasource.db-kind")
20+
String dbKind;
21+
1722
private EntityManager em;
1823

1924
@Inject
@@ -25,14 +30,32 @@ public ProcessEventDao(EntityManager em) {
2530
public List<ProcessEventTable> getEventsForLabelAndType(String label, EventType eventType,
2631
ProjectVersionTable projectVersionTable) {
2732

28-
return em //
29-
.createQuery(
30-
"SELECT e FROM ProcessEventTable e WHERE e.label = :label AND e.eventType=:eventType AND e.project=:project",
31-
ProcessEventTable.class)
32-
.setParameter("label", label)//
33-
.setParameter("eventType", eventType)//
34-
.setParameter("project", projectVersionTable)//
35-
.getResultList();
33+
String searchLabel = SearchLabelBuilder.buildSearchLabel(label);
34+
35+
if ("postgresql".equals(dbKind)) {
36+
return em.createQuery(
37+
"SELECT e FROM ProcessEventTable e " +
38+
"WHERE e.eventType = :eventType " +
39+
"AND e.project = :project " +
40+
"AND ( e.searchLabel = :searchLabel " +
41+
"OR function('levenshtein', e.searchLabel, :searchLabel) <= 4 )",
42+
ProcessEventTable.class)
43+
.setParameter("searchLabel", searchLabel)
44+
.setParameter("eventType", eventType)
45+
.setParameter("project", projectVersionTable)
46+
.getResultList();
47+
} else {
48+
return em.createQuery(
49+
"SELECT e FROM ProcessEventTable e " +
50+
"WHERE e.eventType = :eventType " +
51+
"AND e.project = :project " +
52+
"AND e.searchLabel = :searchLabel ",
53+
ProcessEventTable.class)
54+
.setParameter("searchLabel", searchLabel)
55+
.setParameter("eventType", eventType)
56+
.setParameter("project", projectVersionTable)
57+
.getResultList();
58+
}
3659
}
3760

3861
@Transactional

backend/src/main/java/de/envite/proa/repository/processmodel/ProcessModelDao.java

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import de.envite.proa.entities.process.ProcessType;
44
import de.envite.proa.repository.tables.ProcessModelTable;
55
import de.envite.proa.repository.tables.ProjectVersionTable;
6+
import de.envite.proa.util.SearchLabelBuilder;
67
import jakarta.enterprise.context.RequestScoped;
78
import jakarta.inject.Inject;
89
import jakarta.persistence.EntityGraph;
@@ -13,8 +14,13 @@
1314
import java.util.List;
1415
import java.util.Map;
1516

17+
import org.eclipse.microprofile.config.inject.ConfigProperty;
18+
1619
@RequestScoped
1720
public class ProcessModelDao {
21+
22+
@ConfigProperty(name = "quarkus.datasource.db-kind")
23+
private String dbKind;
1824

1925
private EntityManager em;
2026

@@ -52,16 +58,35 @@ public List<ProcessModelTable> getProcessModelsWithoutCollaborationsAndWithEvent
5258

5359
@Transactional
5460
public List<ProcessModelTable> getProcessModelsForName(String name, ProjectVersionTable projectVersionTable) {
55-
return em
56-
.createQuery(
57-
"SELECT p " +
58-
"FROM ProcessModelTable p " +
59-
"WHERE p.name = :name " +
60-
"AND p.project = :project",
61-
ProcessModelTable.class)
62-
.setParameter("name", name)
63-
.setParameter("project", projectVersionTable)
64-
.getResultList();
61+
62+
if ("postgresql".equals(dbKind)) {
63+
64+
String searchLabel = SearchLabelBuilder.buildSearchLabel(name);
65+
66+
return em
67+
.createQuery(
68+
"SELECT p " +
69+
"FROM ProcessModelTable p " +
70+
"WHERE ( p.name = :name " +
71+
"OR function('levenshtein', p.searchLabel, :searchLabel) <= 4 )" +
72+
"AND p.project = :project",
73+
ProcessModelTable.class)
74+
.setParameter("name", name)
75+
.setParameter("searchLabel", searchLabel)
76+
.setParameter("project", projectVersionTable)
77+
.getResultList();
78+
}else {
79+
return em
80+
.createQuery(
81+
"SELECT p " +
82+
"FROM ProcessModelTable p " +
83+
"WHERE p.name = :name " +
84+
"AND p.project = :project",
85+
ProcessModelTable.class)
86+
.setParameter("name", name)
87+
.setParameter("project", projectVersionTable)
88+
.getResultList();
89+
}
6590
}
6691

6792
@Transactional

backend/src/main/java/de/envite/proa/repository/tables/CallActivityTable.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.envite.proa.repository.tables;
22

3+
import de.envite.proa.util.SearchLabelBuilder;
34
import jakarta.persistence.*;
45
import lombok.Data;
56

@@ -15,9 +16,17 @@ public class CallActivityTable {
1516

1617
private String label;
1718

19+
private String searchLabel;
20+
1821
@ManyToOne(fetch = FetchType.LAZY)
1922
private ProcessModelTable processModel;
2023

2124
@ManyToOne(fetch = FetchType.LAZY)
2225
private ProjectVersionTable project;
26+
27+
@PrePersist
28+
@PreUpdate
29+
private void generateSearchLabel() {
30+
this.searchLabel = SearchLabelBuilder.buildSearchLabel(this.label);
31+
}
2332
}

backend/src/main/java/de/envite/proa/repository/tables/DataStoreTable.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.envite.proa.repository.tables;
22

3+
import de.envite.proa.util.SearchLabelBuilder;
34
import jakarta.persistence.*;
45
import lombok.Data;
56

@@ -13,6 +14,14 @@ public class DataStoreTable {
1314

1415
private String label;
1516

17+
private String searchLabel;
18+
1619
@ManyToOne(fetch = FetchType.LAZY)
1720
private ProjectVersionTable project;
21+
22+
@PrePersist
23+
@PreUpdate
24+
private void generateSearchLabel() {
25+
this.searchLabel = SearchLabelBuilder.buildSearchLabel(this.label);
26+
}
1827
}

backend/src/main/java/de/envite/proa/repository/tables/ProcessEventTable.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.envite.proa.repository.tables;
22

33
import de.envite.proa.entities.process.EventType;
4+
import de.envite.proa.util.SearchLabelBuilder;
45
import jakarta.persistence.*;
56
import lombok.Data;
67

@@ -16,12 +17,20 @@ public class ProcessEventTable {
1617

1718
private String label;
1819

20+
private String searchLabel;
21+
1922
@Enumerated(EnumType.STRING)
2023
private EventType eventType;
2124

2225
@ManyToOne(fetch = FetchType.LAZY)
2326
private ProcessModelTable processModel;
2427

2528
@ManyToOne(fetch = FetchType.LAZY)
26-
private ProjectVersionTable project;
29+
private ProjectVersionTable project;
30+
31+
@PrePersist
32+
@PreUpdate
33+
private void generateSearchLabel() {
34+
this.searchLabel = SearchLabelBuilder.buildSearchLabel(this.label);
35+
}
2736
}

backend/src/main/java/de/envite/proa/repository/tables/ProcessModelTable.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package de.envite.proa.repository.tables;
22

33
import de.envite.proa.entities.process.ProcessType;
4+
import de.envite.proa.util.SearchLabelBuilder;
45
import jakarta.persistence.*;
56
import lombok.Data;
67
import lombok.EqualsAndHashCode;
@@ -56,6 +57,8 @@ public ProcessModelTable(Long id) {
5657

5758
@EqualsAndHashCode.Include
5859
private String name;
60+
61+
private String searchLabel;
5962

6063
@EqualsAndHashCode.Include
6164
private String bpmnProcessId;
@@ -77,7 +80,7 @@ public ProcessModelTable(Long id) {
7780
@Column
7881
@EqualsAndHashCode.Include
7982
private String description;
80-
83+
8184
@Column
8285
@EqualsAndHashCode.Include
8386
private LocalDateTime createdAt;
@@ -99,4 +102,10 @@ public ProcessModelTable(Long id) {
99102

100103
@EqualsAndHashCode.Include
101104
private ProcessType processType;
105+
106+
@PrePersist
107+
@PreUpdate
108+
private void generateSearchLabel() {
109+
this.searchLabel = SearchLabelBuilder.buildSearchLabel(this.name);
110+
}
102111
}

0 commit comments

Comments
 (0)