use of io.lumeer.api.model.Rule in project engine by Lumeer.
the class LinkTypeFacade method upsertRule.
public LinkType upsertRule(final String linkTypeId, final String ruleId, final Rule rule) {
final LinkType linkType = checkLinkTypePermission(linkTypeId, RoleType.TechConfig);
LinkType originalLinkType = new LinkType(linkType);
Map<String, Rule> rules = Objects.requireNonNullElse(linkType.getRules(), new HashMap<>());
Rule originalRule = rules.get(ruleId);
rule.checkConfiguration(originalRule);
permissionsChecker.checkRulePermissions(rule);
rules.put(ruleId, rule);
linkType.setRules(rules);
mapLinkTypeUpdateValues(linkType);
final LinkType updatedLinkType = linkTypeDao.updateLinkType(linkType.getId(), linkType, originalLinkType);
return mapLinkTypeData(updatedLinkType);
}
use of io.lumeer.api.model.Rule in project engine by Lumeer.
the class TaskProcessingFacadeIT method testEndlessLoopBlocklyRules.
@Test
public void testEndlessLoopBlocklyRules() throws InterruptedException {
final String ruleName = "blocklyRule";
final Collection c1 = createCollection("c1", "name1", Map.of("a0", "A", "a1", "B"));
final Document c1d1 = documentFacade.createDocument(c1.getId(), new Document(new DataDocument("a0", "line1").append("a1", 10)));
final Document c1d2 = documentFacade.createDocument(c1.getId(), new Document(new DataDocument("a0", "line2").append("a1", 20)));
final BlocklyRule rule = new BlocklyRule(new Rule(ruleName, Rule.RuleType.BLOCKLY, Rule.RuleTiming.UPDATE, new DataDocument()));
rule.setDryRun(false);
rule.setResultTimestamp(0);
rule.setJs("var i, newDocument;\n" + "\n" + "\n" + "var lumeer = Polyglot.import('lumeer');\n" + "while (true) {}");
c1.getRules().put(ruleName, rule.getRule());
collectionFacade.updateCollection(c1.getId(), c1);
collectionFacade.upsertRule(c1.getId(), ruleName, rule.getRule());
documentFacade.patchDocumentData(c1.getId(), c1d1.getId(), new DataDocument("a1", 11));
Collection updatedCollection;
BlocklyRule updatedRule;
Thread.sleep(5000);
updatedCollection = collectionFacade.getCollection(c1.getId());
updatedRule = new BlocklyRule(updatedCollection.getRules().get(ruleName));
final String error = updatedRule.getError();
assertThat(error.contains("Execution got cancelled") || error.contains("Thread was interrupted")).isTrue();
// it should have been interrupted after 3000ms
assertThat(System.currentTimeMillis() - updatedRule.getResultTimestamp()).isLessThan(5000);
}
use of io.lumeer.api.model.Rule in project engine by Lumeer.
the class TaskProcessingFacadeIT method testBlocklyRules.
@Test
public void testBlocklyRules() throws InterruptedException {
final String ruleName = "blocklyRule";
final Collection c1 = createCollection("c1", "name1", Map.of("a0", "A", "a1", "B"));
final Collection c2 = createCollection("c2", "name2", Map.of("a0", "C", "a1", "D"));
final LinkType l = linkTypeFacade.createLinkType(new LinkType("link1", List.of(c1.getId(), c2.getId()), Collections.emptyList(), null, null, null));
final Document c1d1 = documentFacade.createDocument(c1.getId(), new Document(new DataDocument("a0", "line1").append("a1", 10)));
final Document c1d2 = documentFacade.createDocument(c1.getId(), new Document(new DataDocument("a0", "line2").append("a1", 20)));
final Document c2d1 = documentFacade.createDocument(c2.getId(), new Document(new DataDocument("a0", "subline1").append("a1", "")));
final Document c2d2 = documentFacade.createDocument(c2.getId(), new Document(new DataDocument("a0", "subline2").append("a1", "")));
final Document c2d3 = documentFacade.createDocument(c2.getId(), new Document(new DataDocument("a0", "subline3").append("a1", "")));
linkInstanceFacade.createLinkInstance(new LinkInstance(l.getId(), List.of(c1d1.getId(), c2d1.getId())));
linkInstanceFacade.createLinkInstance(new LinkInstance(l.getId(), List.of(c1d1.getId(), c2d2.getId())));
final BlocklyRule rule = new BlocklyRule(new Rule(ruleName, Rule.RuleType.BLOCKLY, Rule.RuleTiming.UPDATE, new DataDocument()));
rule.setDryRun(true);
rule.setJs("var i, newDocument;\n" + "\n" + "\n" + "var lumeer = Polyglot.import('lumeer');\n" + " var i_list = lumeer.getLinkedDocuments(newDocument, '" + l.getId() + "');\n" + " for (var i_index in i_list) {\n" + " i = i_list[i_index];\n" + " lumeer.setDocumentAttribute(i, 'a1', lumeer.getDocumentAttribute(newDocument, 'a1'))}\n");
c1.getRules().put(ruleName, rule.getRule());
collectionFacade.updateCollection(c1.getId(), c1);
collectionFacade.upsertRule(c1.getId(), ruleName, rule.getRule());
documentFacade.patchDocumentData(c1.getId(), c1d1.getId(), new DataDocument("a1", 11));
Collection updatedCollection;
BlocklyRule updatedRule;
int cycles = 10;
do {
Thread.sleep(500);
updatedCollection = collectionFacade.getCollection(c1.getId());
updatedRule = new BlocklyRule(updatedCollection.getRules().get(ruleName));
} while (updatedRule.getDryRunResult() == null && cycles-- > 0);
assertThat(updatedRule.getDryRunResult()).matches(Pattern.compile("^name2......: D = 11\\.0\nname2......: D = 11\\.0\n$"));
assertThat(System.currentTimeMillis() - updatedRule.getResultTimestamp()).isLessThan(5000);
// It was a dry run, no changes should have been introduced
Document c2d1updated = documentFacade.getDocument(c2d1.getCollectionId(), c2d1.getId());
Document c2d2updated = documentFacade.getDocument(c2d2.getCollectionId(), c2d2.getId());
assertThat(c2d1updated.getData().get("a1")).isInstanceOf(String.class).isEqualTo("");
assertThat(c2d2updated.getData().get("a1")).isInstanceOf(String.class).isEqualTo("");
// Run it for real
rule.setDryRun(false);
rule.setResultTimestamp(0);
c1.getRules().put(ruleName, rule.getRule());
collectionFacade.updateCollection(c1.getId(), c1);
collectionFacade.upsertRule(c1.getId(), ruleName, rule.getRule());
documentFacade.patchDocumentData(c1.getId(), c1d1.getId(), new DataDocument("a1", 12));
cycles = 10;
do {
Thread.sleep(500);
updatedCollection = collectionFacade.getCollection(c1.getId());
updatedRule = new BlocklyRule(updatedCollection.getRules().get(ruleName));
} while (updatedRule.getResultTimestamp() == 0 && cycles-- > 0);
c2d1updated = documentFacade.getDocument(c2d1.getCollectionId(), c2d1.getId());
c2d2updated = documentFacade.getDocument(c2d2.getCollectionId(), c2d2.getId());
assertThat(c2d1updated.getData().get("a1")).isInstanceOf(Number.class).isEqualTo(12.0);
assertThat(c2d2updated.getData().get("a1")).isInstanceOf(Number.class).isEqualTo(12.0);
}
use of io.lumeer.api.model.Rule in project engine by Lumeer.
the class LinkTypeCodec method decode.
@Override
public LinkType decode(final BsonReader reader, final DecoderContext decoderContext) {
Document bson = documentCodec.decode(reader, decoderContext);
String id = bson.getObjectId(ID).toHexString();
String name = bson.getString(NAME);
List<String> collectionCodes = bson.get(COLLECTION_IDS, List.class);
List<Attribute> attributes = new ArrayList<Document>(bson.get(ATTRIBUTES, List.class)).stream().map(AttributeCodec::convertFromDocument).collect(Collectors.toList());
Long version = bson.getLong(VERSION);
Integer lastAttributeNum = bson.getInteger(LAST_ATTRIBUTE_NUM);
Map<String, Rule> rules = new HashMap<>();
Document rulesMap = bson.get(RULES, Document.class);
if (rulesMap != null) {
rulesMap.forEach((k, v) -> {
final Rule rule = RuleCodec.convertFromDocument(rulesMap.get(k, Document.class));
if (StringUtils.isEmpty(rule.getName())) {
rule.setName(k);
}
rules.put(k, rule);
});
}
Permissions permissions = PermissionsCodec.convertFromDocument(bson.get(ROLES, Document.class));
LinkPermissionsType permissionsType = LinkPermissionsType.fromString(bson.getString(ROLES_TYPE));
Date creationDate = bson.getDate(CREATION_DATE);
ZonedDateTime creationZonedDate = creationDate != null ? ZonedDateTime.ofInstant(creationDate.toInstant(), ZoneOffset.UTC) : null;
String createdBy = bson.getString(CREATED_BY);
Date updateDate = bson.getDate(UPDATE_DATE);
ZonedDateTime updatedZonedDate = updateDate != null ? ZonedDateTime.ofInstant(updateDate.toInstant(), ZoneOffset.UTC) : null;
String updatedBy = bson.getString(UPDATED_BY);
LinkType linkType = new LinkType(name, collectionCodes, attributes, rules, permissions, permissionsType);
linkType.setId(id);
linkType.setVersion(version == null ? 0 : version);
linkType.setLastAttributeNum(lastAttributeNum);
linkType.setCreatedBy(createdBy);
linkType.setCreationDate(creationZonedDate);
linkType.setUpdatedBy(updatedBy);
linkType.setUpdateDate(updatedZonedDate);
return linkType;
}
Aggregations