Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions application-engine/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,6 @@ services:
- MINIO_ROOT_USER=root
- MINIO_ROOT_PASSWORD=password
- MINIO_DEFAULT_BUCKETS=default
networks:
minionetwork:
driver: bridge

volumes:
minio_data:
driver: local

# kibana:
# image: docker.elastic.co/kibana/kibana:8.10.4
Expand All @@ -67,3 +60,11 @@ volumes:
# - docker-elastic
# ports:
# - "5601:5601"

networks:
minionetwork:
driver: bridge

volumes:
minio_data:
driver: local
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.netgrif.application.engine.petrinet.domain.dataset.logic.action


import com.netgrif.application.engine.AsyncRunner
import com.netgrif.application.engine.adapter.spring.petrinet.service.ProcessRoleService
import com.netgrif.application.engine.adapter.spring.workflow.domain.QCase
Expand Down Expand Up @@ -31,6 +32,7 @@ import com.netgrif.application.engine.objects.petrinet.domain.*
import com.netgrif.application.engine.objects.petrinet.domain.dataset.*
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.ChangedField
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.FieldBehavior
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.validation.DynamicValidation
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.validation.Validation
import com.netgrif.application.engine.objects.petrinet.domain.roles.ProcessRole
Expand Down Expand Up @@ -59,7 +61,6 @@ import com.netgrif.application.engine.workflow.service.TaskService
import com.netgrif.application.engine.workflow.service.interfaces.*
import com.netgrif.application.engine.workflow.web.responsebodies.MessageResource
import com.netgrif.application.engine.workflow.web.responsebodies.TaskReference
import com.netgrif.application.engine.objects.petrinet.domain.dataset.logic.action.Action;
import com.querydsl.core.types.Predicate
import groovy.transform.NamedVariant
import org.bson.types.ObjectId
Expand Down Expand Up @@ -1600,6 +1601,10 @@ class ActionDelegate {
@NamedVariant
Case createFilter(def title, String query, String type, List<String> allowedNets,
String icon, String visibility, def filterMetadata) {
if (type == null || type.length() == 0) {
throw new IllegalArgumentException("Filter type cannot be null or empty");
}
type = type.toLowerCase().capitalize()
Case filterCase = createCase(FilterRunner.FILTER_PETRI_NET_IDENTIFIER, title as String)
filterCase.setIcon(icon)
filterCase.dataSet[DefaultFiltersRunner.FILTER_I18N_TITLE_FIELD_ID].value = (title instanceof I18nString) ? title : new I18nString(title as String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ protected Optional<DataField> transformDataField(String fieldId, Case useCase) {
return this.transformUserListField(caseField);
} else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) {
return this.transformI18nField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField) netField);
} else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField) {
return this.transformCaseFieldField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField) netField);
} else if (netField instanceof com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField) {
return this.transformFilterFieldField(caseField, (com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField) netField);
} else {
String string = caseField.getValue().toString();
if (string == null)
Expand All @@ -87,7 +91,8 @@ protected Optional<DataField> transformDataField(String fieldId, Case useCase) {
}
}

protected Optional<DataField> transformMultichoiceMapField(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceMap, MultichoiceMapField netField) {
protected Optional<DataField> transformMultichoiceMapField
(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceMap, MultichoiceMapField netField) {
Optional<Set> optValues = this.getMultichoiceValue(multichoiceMap, netField);
if (!optValues.isPresent()) {
return Optional.empty();
Expand All @@ -101,27 +106,44 @@ protected Optional<DataField> transformMultichoiceMapField(com.netgrif.applicati
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField(values));
}

protected Optional<DataField> transformI18nField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField netField) {
protected Optional<DataField> transformI18nField
(com.netgrif.application.engine.objects.workflow.domain.DataField
dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.I18nField netField) {
Set<String> keys = ((I18nString) dataField.getValue()).getTranslations().keySet();
Set<String> values = new HashSet<>(((I18nString) dataField.getValue()).getTranslations().values());
values.add(((I18nString) dataField.getValue()).getDefaultValue());
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.I18nField(keys, values));
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.I18nField(keys, values, ((I18nString) dataField.getValue()).getTranslations()));
}

protected Optional<DataField> transformEnumerationMapField(com.netgrif.application.engine.objects.workflow.domain.DataField enumMap, EnumerationMapField netField) {
protected Optional<DataField> transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets));
}
Comment on lines +118 to +122
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add type safety checks for CaseField transformation.

The method assumes dataField.getValue() returns List<String> and that getAllowedNets() exists on the workflow DataField. Add null checks and type verification to prevent runtime exceptions.

 protected Optional<DataField> transformCaseFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.CaseField netField) {
+    if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
+        return Optional.empty();
+    }
+    if (!(dataField.getValue() instanceof List)) {
+        log.error("CaseField value is not a List. Found: " + dataField.getValue().getClass().getCanonicalName());
+        return Optional.empty();
+    }
     String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
-    String[] referencedCases = ((List<String>) dataField.getValue()).toArray(new String[0]);
+    List<?> valueList = (List<?>) dataField.getValue();
+    String[] referencedCases = valueList.stream()
+        .filter(Objects::nonNull)
+        .map(Object::toString)
+        .toArray(String[]::new);
     return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.CaseField(referencedCases,allowedNets));
 }
🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
around lines 118 to 122, the method transformCaseFieldField assumes
dataField.getValue() returns a List<String> and that getAllowedNets() is
non-null, which can cause runtime exceptions. Add null checks to verify
dataField.getValue() is not null and is an instance of List<?> before casting,
and ensure getAllowedNets() is not null before converting to array. If checks
fail, handle gracefully by returning Optional.empty() or an appropriate
fallback.


protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
}
Comment on lines +124 to +128
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add error handling for FilterField transformation.

The method assumes getAllowedNets() and getFilterMetadata() methods exist and that the value can be safely converted to string. Add proper null checks and error handling.

 protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
+    if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
+        return Optional.empty();
+    }
     String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
     Map<String, Object> filterMetadata = dataField.getFilterMetadata();
+    if (filterMetadata == null) {
+        filterMetadata = new HashMap<>();
+    }
     return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(dataField.getValue().toString(),allowedNets, filterMetadata));
}
protected Optional<DataField> transformFilterFieldField(com.netgrif.application.engine.objects.workflow.domain.DataField dataField, com.netgrif.application.engine.objects.petrinet.domain.dataset.FilterField netField) {
if (dataField.getValue() == null || dataField.getAllowedNets() == null) {
return Optional.empty();
}
String[] allowedNets = dataField.getAllowedNets().toArray(new String[0]);
Map<String, Object> filterMetadata = dataField.getFilterMetadata();
if (filterMetadata == null) {
filterMetadata = new HashMap<>();
}
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FilterField(
dataField.getValue().toString(),
allowedNets,
filterMetadata
));
}
🤖 Prompt for AI Agents
In
application-engine/src/main/java/com/netgrif/application/engine/elastic/service/ElasticCaseMappingService.java
around lines 124 to 128, the method transformFilterFieldField assumes
getAllowedNets(), getFilterMetadata(), and dataField.getValue() are non-null and
safely convertible to string. Add null checks for dataField, its allowedNets,
filterMetadata, and value before using them. If any are null, handle gracefully
by returning Optional.empty() or a default value. Also, wrap the conversion to
string in a try-catch block to handle potential exceptions and avoid runtime
errors.

Comment thread
renczesstefan marked this conversation as resolved.

protected Optional<DataField> transformEnumerationMapField
(com.netgrif.application.engine.objects.workflow.domain.DataField enumMap, EnumerationMapField netField) {
Map<String, I18nString> options = this.getFieldOptions(enumMap, netField);
String selectedKey = (String) enumMap.getValue();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.MapField(new AbstractMap.SimpleEntry<>(selectedKey, collectTranslations(options.get(selectedKey)))));
}

private Map<String, I18nString> getFieldOptions(com.netgrif.application.engine.objects.workflow.domain.DataField map, MapOptionsField<I18nString, ?> netField) {
private Map<String, I18nString> getFieldOptions
(com.netgrif.application.engine.objects.workflow.domain.DataField map, MapOptionsField<I18nString, ?> netField) {
if (map.getOptions() != null) {
return map.getOptions();
}
return netField.getOptions();
}

protected Optional<DataField> transformMultichoiceField(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceField, MultichoiceField netField) {
protected Optional<DataField> transformMultichoiceField
(com.netgrif.application.engine.objects.workflow.domain.DataField multichoiceField, MultichoiceField netField) {
Optional<Set> optValues = this.getMultichoiceValue(multichoiceField, netField);
if (!optValues.isPresent()) {
return Optional.empty();
Expand All @@ -142,7 +164,8 @@ protected Optional<DataField> transformMultichoiceField(com.netgrif.application.
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(translations.toArray(new String[0])));
}

private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects.workflow.domain.DataField multichoice, Field netField) {
private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects.workflow.domain.DataField
multichoice, Field netField) {
if (multichoice.getValue() instanceof Set) {
return Optional.of((Set) multichoice.getValue());
} else if (multichoice.getValue() instanceof Collection) {
Expand All @@ -157,7 +180,8 @@ private Optional<Set> getMultichoiceValue(com.netgrif.application.engine.objects
}
}

protected Optional<DataField> transformEnumerationField(com.netgrif.application.engine.objects.workflow.domain.DataField enumField) {
protected Optional<DataField> transformEnumerationField
(com.netgrif.application.engine.objects.workflow.domain.DataField enumField) {
Object value = enumField.getValue();
if (value instanceof I18nString) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(this.collectTranslations((I18nString) value).toArray(new String[0])));
Expand All @@ -180,25 +204,29 @@ protected List<String> collectTranslations(I18nString i18nString) {
return translations;
}

protected Optional<DataField> transformNumberField(com.netgrif.application.engine.objects.workflow.domain.DataField numberField) {
protected Optional<DataField> transformNumberField
(com.netgrif.application.engine.objects.workflow.domain.DataField numberField) {
if (numberField.getValue() instanceof Integer) { //TODO: Refactor
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.NumberField(Double.parseDouble(numberField.getValue().toString())));
}
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.NumberField((Double) numberField.getValue()));
}

protected Optional<DataField> transformButtonField(com.netgrif.application.engine.objects.workflow.domain.DataField buttonField) {
protected Optional<DataField> transformButtonField
(com.netgrif.application.engine.objects.workflow.domain.DataField buttonField) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.ButtonField((Integer) buttonField.getValue()));
}

protected Optional<DataField> transformUserField(com.netgrif.application.engine.objects.workflow.domain.DataField userField) {
protected Optional<DataField> transformUserField
(com.netgrif.application.engine.objects.workflow.domain.DataField userField) {
UserFieldValue user = (UserFieldValue) userField.getValue();
if (user == null)
return Optional.empty();
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserField(this.transformUserValue(user)));
}

protected Optional<DataField> transformUserListField(com.netgrif.application.engine.objects.workflow.domain.DataField userListField) {
protected Optional<DataField> transformUserListField
(com.netgrif.application.engine.objects.workflow.domain.DataField userListField) {
UserListFieldValue userListValue = (UserListFieldValue) userListField.getValue();
UserField.UserMappingData[] userMappingData = userListValue.getUserValues().stream().map(this::transformUserListValue).toArray(UserField.UserMappingData[]::new);
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.UserListField(userMappingData));
Expand All @@ -224,7 +252,9 @@ private StringBuilder buildFullName(String name, String surname) {
return fullName;
}

protected Optional<DataField> transformDateField(com.netgrif.application.engine.objects.workflow.domain.DataField dateField, com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField netField) {
protected Optional<DataField> transformDateField
(com.netgrif.application.engine.objects.workflow.domain.DataField
dateField, com.netgrif.application.engine.objects.petrinet.domain.dataset.DateField netField) {
if (dateField.getValue() instanceof LocalDate) {
LocalDate date = (LocalDate) dateField.getValue();
return formatDateField(LocalDateTime.of(date, LocalTime.NOON));
Expand All @@ -239,7 +269,8 @@ protected Optional<DataField> transformDateField(com.netgrif.application.engine.
}
}

protected Optional<DataField> transformDateTimeField(com.netgrif.application.engine.objects.workflow.domain.DataField dateTimeField, DateTimeField netField) {
protected Optional<DataField> transformDateTimeField
(com.netgrif.application.engine.objects.workflow.domain.DataField dateTimeField, DateTimeField netField) {
if (dateTimeField.getValue() instanceof LocalDateTime) {
return formatDateField((LocalDateTime) dateTimeField.getValue());
} else if (dateTimeField.getValue() instanceof Date) {
Expand All @@ -252,7 +283,8 @@ protected Optional<DataField> transformDateTimeField(com.netgrif.application.eng
}
}

private LocalDateTime transformDateValueField(com.netgrif.application.engine.objects.workflow.domain.DataField dateValueField) {
private LocalDateTime transformDateValueField(com.netgrif.application.engine.objects.workflow.domain.DataField
dateValueField) {
return ((Date) dateValueField.getValue()).toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
Expand All @@ -264,26 +296,31 @@ private Optional<DataField> formatDateField(LocalDateTime date) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.DateField(date.format(DateTimeFormatter.BASIC_ISO_DATE), date));
}

protected Optional<DataField> transformBooleanField(com.netgrif.application.engine.objects.workflow.domain.DataField booleanField) {
protected Optional<DataField> transformBooleanField
(com.netgrif.application.engine.objects.workflow.domain.DataField booleanField) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.BooleanField((Boolean) booleanField.getValue()));
}

protected Optional<DataField> transformTextField(com.netgrif.application.engine.objects.workflow.domain.DataField textField) {
protected Optional<DataField> transformTextField
(com.netgrif.application.engine.objects.workflow.domain.DataField textField) {
if (textField.getValue() == null) {
return Optional.empty();
}
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField((String) textField.getValue()));
}

protected Optional<DataField> transformFileField(com.netgrif.application.engine.objects.workflow.domain.DataField fileField) {
protected Optional<DataField> transformFileField
(com.netgrif.application.engine.objects.workflow.domain.DataField fileField) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField((FileFieldValue) fileField.getValue()));
}

protected Optional<DataField> transformFileListField(com.netgrif.application.engine.objects.workflow.domain.DataField fileListField) {
protected Optional<DataField> transformFileListField
(com.netgrif.application.engine.objects.workflow.domain.DataField fileListField) {
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.FileField(((FileListFieldValue) fileListField.getValue()).getNamesPaths().toArray(new FileFieldValue[0])));
}

protected Optional<DataField> transformOtherFields(com.netgrif.application.engine.objects.workflow.domain.DataField otherField, Field netField) {
protected Optional<DataField> transformOtherFields
(com.netgrif.application.engine.objects.workflow.domain.DataField otherField, Field netField) {
log.warn("Field of type " + netField.getClass().getCanonicalName() + " is not supported for indexation by default. Indexing the toString() representation of its value...");
return Optional.of(new com.netgrif.application.engine.adapter.spring.elastic.domain.TextField(otherField.getValue().toString()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public Task(com.netgrif.application.engine.objects.workflow.domain.Task task, Lo
this.caseTitle = task.getCaseTitle();
this.priority = task.getPriority();
this.userId = task.getUser() != null ? task.getUser().getStringId() : null;
this.userRealmId = task.getUserRealmId() != null ? task.getUser().getRealmId() : null;
this.userRealmId = task.getUser() != null ? task.getUser().getRealmId() : null;
this.roles = task.getRoles();
this.users = task.getUsers();
this.startDate = task.getStartDate();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -341,6 +341,9 @@ public boolean validateRequiredAttributes() {

@Override
public String getTelNumber() {
if (attributes == null) {
return null;
}
if (attributes.containsKey("tel")) {
return (String) attributes.get("tel").getValue();
}
Expand All @@ -349,9 +352,13 @@ public String getTelNumber() {

@Override
public void setTelNumber(String telNumber) {
if (attributes == null) {
attributes = new HashMap<>();
}
if (attributes.containsKey("tel")) {
((Attribute<String>) attributes.get("tel")).setValue(telNumber);
}
attributes.put("tel", new Attribute<>(telNumber, false));
Comment thread
renczesstefan marked this conversation as resolved.
Comment thread
renczesstefan marked this conversation as resolved.
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public BooleanField(Boolean value) {
super(value.toString());
this.booleanValue = value;
}

@Override
public Object getValue() {
return booleanValue;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,9 @@ public ButtonField(Integer value) {
super(value.toString());
this.buttonValue = value;
}

@Override
public Object getValue() {
return buttonValue;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.netgrif.application.engine.objects.elastic.domain;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

@Data
@NoArgsConstructor
@EqualsAndHashCode(callSuper = true)
public abstract class CaseField extends FieldWithAllowedNetsField {

public CaseField(String[] fullTextValue, String[] allowedNets) {
super(fullTextValue, allowedNets);
}

@Override
public Object getValue() {
return new ArrayList<>(List.of(fulltextValue));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ public abstract class DataField implements Serializable {
this.fulltextValue = new String[1];
this.fulltextValue[0] = fulltextValue;
}

public Object getValue() {
return (fulltextValue != null && fulltextValue.length > 0) ? fulltextValue[0] : null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ public DateField(String value, LocalDateTime dateTime) {
this.dateValue = dateTime;
this.timestampValue = Timestamp.valueOf(dateTime).getTime();
}

@Override
public Object getValue() {
return dateValue;
}
}
Loading
Loading