diff --git a/LIQUIBASE/changelog/db-changelog-master.xml b/LIQUIBASE/changelog/db-changelog-master.xml
index 9374cabc2..8a3a3fd31 100644
--- a/LIQUIBASE/changelog/db-changelog-master.xml
+++ b/LIQUIBASE/changelog/db-changelog-master.xml
@@ -96,5 +96,5 @@
+
-
diff --git a/LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml b/LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml
new file mode 100644
index 000000000..0c10a0faf
--- /dev/null
+++ b/LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml
@@ -0,0 +1,501 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template_id = 2000
+
+
+ template_id = 2001
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20001
+
+
+ br_id = 'VP-L00-00-0001'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20002
+
+
+ br_id = 'VP-L01-00-0002'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20003
+
+
+ br_id = 'VP-L01-00-0003'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20006
+
+
+ br_id = 'VP-L01-00-0006'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20007
+
+
+ br_id = 'VP-L03-00-0007'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 30006
+
+
+ br_id = 'VP-L00-00-0006'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20009
+
+
+ br_id = 'VP-L01-00-0009'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20010
+
+
+ br_id = 'VP-L01-00-0010'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 30020
+
+
+ br_id = 'VP-L00-00-0020'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template_id = 2002
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20021
+
+
+ br_id = 'VP-L01-00-0021'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20022
+
+
+ br_id = 'VP-L01-00-0022'
+
+
+
+
+
+
+
+
+
+
+
+
+
+ template_id = 2003
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 20101
+
+
+ br_id = 'VP-L01-00-0101'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 30200
+
+
+ br_id = 'VP-L00-00-0200'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 30201
+
+
+ br_id = 'VP-L01-00-0201'
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ rule_id = 30202
+
+
+ br_id = 'VP-L01-00-0202'
+
+
+
+
+
diff --git a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/bean/RulesDomainModelBean.java b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/bean/RulesDomainModelBean.java
index 6d084d7be..658f77334 100644
--- a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/bean/RulesDomainModelBean.java
+++ b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/bean/RulesDomainModelBean.java
@@ -16,6 +16,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.schema.rules.customrule.v1.*;
import eu.europa.ec.fisheries.schema.rules.previous.v1.PreviousReportType;
import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMessageType;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.schema.rules.rule.v1.RuleType;
import eu.europa.ec.fisheries.schema.rules.rule.v1.ValidationMessageType;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmQuery;
@@ -125,6 +126,15 @@ public void updateValidationMessagesWithPermission(ValidationMessageType validat
}
}
+ @Override
+ public void createOrUpdateValidationMessagesWithPermission(ValidationMessageType validationMessage, String rawMsgGuid, String rawMessage, RawMsgType type) throws RulesModelException {
+ try {
+ rulesDao.createOrUpdateValidationMessagesWithPermission(rawMsgGuid, rawMessage, type, RawMessageMapper.INSTANCE.mapToValidationMessageEntity(validationMessage));
+ } catch (DaoException e) {
+ throw new RulesModelException(e.getMessage(), e);
+ }
+ }
+
@Override
public CustomRuleType createCustomRule(CustomRuleType customRule) throws RulesModelException {
LOG.debug("Create in Rules");
diff --git a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/RulesDao.java b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/RulesDao.java
index 05ffc0649..be2c80216 100644
--- a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/RulesDao.java
+++ b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/RulesDao.java
@@ -15,6 +15,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import java.util.List;
import java.util.Set;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.uvms.commons.service.exception.ServiceException;
import eu.europa.ec.fisheries.uvms.rules.entity.AlarmReport;
import eu.europa.ec.fisheries.uvms.rules.entity.CustomRule;
@@ -160,6 +161,8 @@ List getTicketListPaginated(Integer page, Integer listSize, String sql,
void updateValidationMessagesWith(String rawMessageGuid, String type, ValidationMessage validationMessage) throws DaoException;
+ void createOrUpdateValidationMessagesWithPermission(String rawMessageGuid, String rawMessage, RawMsgType type, ValidationMessage validationMessage) throws DaoException;
+
List getValidationMessagesById(List ids) throws DaoException;
List getValidationMessagesByRawMsgGuid(String rawMsgGuid, String type) throws DaoException;
diff --git a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/bean/RulesDaoBean.java b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/bean/RulesDaoBean.java
index b783f6e37..05888df01 100644
--- a/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/bean/RulesDaoBean.java
+++ b/domain/src/main/java/eu/europa/ec/fisheries/uvms/rules/dao/bean/RulesDaoBean.java
@@ -22,10 +22,12 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import javax.persistence.TransactionRequiredException;
import javax.persistence.TypedQuery;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.uvms.commons.service.exception.ServiceException;
import eu.europa.ec.fisheries.uvms.rules.constant.UvmsConstants;
import eu.europa.ec.fisheries.uvms.rules.dao.FADocumentIDDAO;
@@ -559,7 +561,7 @@ public void saveValidationMessages(List rawMessages) throws DaoExcep
@Override
public void updateValidationMessagesWith(String rawMessageGuid, String type, ValidationMessage validationMessage) throws DaoException {
try {
- List rawMessageByGuid = rawMessageDao.getRawMessageByGuid(rawMessageGuid, type);
+ List rawMessageByGuid = rawMessageDao.getRawMessageByGuid(rawMessageGuid, type);
rawMessageByGuid.forEach(r -> {
r.getValidationMessages().add(validationMessage);
validationMessage.setRawMessage(r);
@@ -569,6 +571,29 @@ public void updateValidationMessagesWith(String rawMessageGuid, String type, Val
}
}
+ @Override
+ public void createOrUpdateValidationMessagesWithPermission(String rawMessageGuid, String rawMessageContent, RawMsgType type, ValidationMessage validationMessage) throws DaoException {
+ try {
+ List rawMessageByGuid = rawMessageDao.getRawMessageByGuid(rawMessageGuid, type.value());
+ if (rawMessageByGuid.isEmpty()) {
+ RawMessage rawMessage = new RawMessage();
+ rawMessage.setGuid(rawMessageGuid);
+ rawMessage.setRawMessage(rawMessageContent);
+ rawMessage.setRawMsgType(type);
+ validationMessage.setRawMessage(rawMessage);
+ rawMessage.setValidationMessages(Collections.singleton(validationMessage));
+ rawMessageDao.saveRawMessages(Collections.singletonList(rawMessage));
+ } else {
+ rawMessageByGuid.forEach(r -> {
+ r.getValidationMessages().add(validationMessage);
+ validationMessage.setRawMessage(r);
+ });
+ }
+ } catch (ServiceException e) {
+ throw new DaoException(e.getMessage(), e);
+ }
+ }
+
@Override
public List getValidationMessagesById(List ids) throws DaoException {
try {
diff --git a/model/src/main/java/eu/europa/ec/fisheries/remote/RulesDomainModel.java b/model/src/main/java/eu/europa/ec/fisheries/remote/RulesDomainModel.java
index 7a367a87f..165cbc10a 100755
--- a/model/src/main/java/eu/europa/ec/fisheries/remote/RulesDomainModel.java
+++ b/model/src/main/java/eu/europa/ec/fisheries/remote/RulesDomainModel.java
@@ -20,6 +20,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.schema.rules.customrule.v1.UpdateSubscriptionType;
import eu.europa.ec.fisheries.schema.rules.previous.v1.PreviousReportType;
import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMessageType;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.schema.rules.rule.v1.ValidationMessageType;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmQuery;
import eu.europa.ec.fisheries.schema.rules.search.v1.CustomRuleQuery;
@@ -115,4 +116,6 @@ public interface RulesDomainModel {
List getValidationMessagesByRawMsgGuid(String rawMsgGuid, String type) throws RulesModelException;
void updateValidationMessagesWithPermission(ValidationMessageType validationMessage, String rawMsgGuid, String type) throws RulesModelException;
-}
\ No newline at end of file
+
+ void createOrUpdateValidationMessagesWithPermission(ValidationMessageType validationMessage, String rawMsgGuid, String rawMessage, RawMsgType type) throws RulesModelException;
+}
diff --git a/model/src/main/resources/contract/Template.xsd b/model/src/main/resources/contract/Template.xsd
index 61604e8d6..e07152f21 100755
--- a/model/src/main/resources/contract/Template.xsd
+++ b/model/src/main/resources/contract/Template.xsd
@@ -86,6 +86,11 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/ContainerType.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/ContainerType.java
index 38b2da827..7d529af6d 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/ContainerType.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/ContainerType.java
@@ -45,7 +45,10 @@ public enum ContainerType {
FactType.SALES_FISHING_TRIP, FactType.SALES_FLUX_LOCATION, FactType.SALES_FLUX_GEOGRAPHICAL_COORDINATE,
FactType.SALES_STRUCTURED_ADDRESS, FactType.SALES_QUERY, FactType.SALES_FLUX_RESPONSE_DOCUMENT,
FactType.SALES_VALIDATION_RESULT_DOCUMENT, FactType.SALES_VALIDATION_QUALITY_ANALYSIS,FactType.SALES_REPORT_WRAPPER,
- FactType.SALES_AUCTION_SALE, FactType.SALES_FLUX_SALES_QUERY_MESSAGE, FactType.SALES_QUERY_PARAMETER, FactType.SALES_FLUX_SALES_RESPONSE_MESSAGE);
+ FactType.SALES_AUCTION_SALE, FactType.SALES_FLUX_SALES_QUERY_MESSAGE, FactType.SALES_QUERY_PARAMETER, FactType.SALES_FLUX_SALES_RESPONSE_MESSAGE),
+
+ MOVEMENTS("movement","ec.europa.eu.movement", FactType.MOVEMENT_REPORT_DOCUMENT, FactType.MOVEMENT_REPORT_DOCUMENT_ID,
+ FactType.MOVEMENT_REPORT_DOC_OWNER_FLUX_PARTY_ID, FactType.MOVEMENT_VESSEL_TRANSPORT_MEANS_ID);
private final String packageName;
private final String containerName;
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulePostProcessBean.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulePostProcessBean.java
index 153f40bd5..5463948e1 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulePostProcessBean.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulePostProcessBean.java
@@ -112,9 +112,13 @@ private void saveValidationResult(List validationMessageT
}
}
+ public void createOrUpdateValidationResult(String rawMsgGuid, String rawMessage, RawMsgType type, RuleError ruleError) throws RulesModelException {
+ final ValidationMessageType validationMessage = createValidationMessageFromParams(ruleError.getRuleId(), ErrorType.ERROR, ruleError.getMessage(), ruleError.getLevel(), Collections.emptyList(), ruleError.getXpaths(), new Date());
+ rulesDomainModel.createOrUpdateValidationMessagesWithPermission(validationMessage, rawMsgGuid, rawMessage, type);
+ }
+
private void updateValidationResult(String rawMsgGuid, String type, ValidationMessageType validationMessage) throws RulesModelException {
rulesDomainModel.updateValidationMessagesWithPermission(validationMessage, rawMsgGuid, type);
-
}
private ValidationResult createValidationResultDtoFromParams(boolean isError, boolean isWarning, boolean isOk, List validationMessages) {
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesEngineBean.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesEngineBean.java
index ea9d3ba8a..1470c24e4 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesEngineBean.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesEngineBean.java
@@ -17,7 +17,14 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
import eu.europa.ec.fisheries.uvms.rules.service.business.MessageType;
import eu.europa.ec.fisheries.uvms.rules.service.business.fact.IdType;
-import eu.europa.ec.fisheries.uvms.rules.service.business.generator.*;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.AbstractGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.ActivityFaReportFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.ActivityQueryFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.ActivityResponseFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.MovementFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.SalesQueryFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.SalesReportFactGenerator;
+import eu.europa.ec.fisheries.uvms.rules.service.business.generator.SalesResponseFactGenerator;
import eu.europa.ec.fisheries.uvms.rules.service.business.helper.RuleApplicabilityChecker;
import eu.europa.ec.fisheries.uvms.rules.service.config.BusinessObjectType;
import eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType;
@@ -36,12 +43,19 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
import static eu.europa.ec.fisheries.uvms.rules.service.business.MessageType.PULL;
import static eu.europa.ec.fisheries.uvms.rules.service.business.MessageType.PUSH;
-import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.*;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.RESPONSE_IDS;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.SENDER_RECEIVER;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.XML;
@Stateless
@Slf4j
@@ -67,6 +81,7 @@ public class RulesEngineBean {
private SalesResponseFactGenerator salesResponseFactGenerator;
+
private FaResponseFactMapper faResponseFactMapper;
@EJB
@@ -181,6 +196,22 @@ public Collection evaluate(BusinessObjectType businessObjectType,
return validateFacts(facts, initializer.getContainerByType(ContainerType.SALES), globals, extraValues);
}
+ else if (businessObjectType == BusinessObjectType.RECEIVING_MOVEMENT_MSG){
+ StopWatch stopWatch = StopWatch.createStarted();
+ AbstractGenerator generator = new MovementFactGenerator(PUSH);
+ generator.setBusinessObjectMessage(businessObject);
+ generator.setExtraValueMap(extraValues);
+
+ List facts = generator.generateAllFacts();
+ log.info("Flow Report, Generating the facts took: {} ms", stopWatch.getTime());
+ stopWatch.reset();
+ stopWatch.start();
+
+ Map globals = new HashMap<>();
+ globals.put("mdrService", mdrCacheRuleService);
+ globals.put("appliChecker", appliChecker);
+ return validateFacts(facts, initializer.getContainerByType(ContainerType.MOVEMENTS), globals, extraValues);
+ }
log.info(String.format("It took %s to evaluate the message.", stopwatch));
log.debug(String.format("%s fact instances holding in memory.", AbstractFact.getNumOfInstances()));
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesKieContainerInitializer.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesKieContainerInitializer.java
index 5dae11646..eef73df83 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesKieContainerInitializer.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/RulesKieContainerInitializer.java
@@ -60,6 +60,7 @@ public void init() {
List faTemplatesAndRules = getFaMessageRules(allTemplates);
List salesTemplatesAndRules = getSalesRules(allTemplates);
List faQueryTemplatesAndRules = getFaQueryRules(allTemplates);
+ List movementTemplatesAndRules = getMovementRules(allTemplates);
log.info("Initializing templates and rules for FA-Report facts. Nr. of Rules : {}", countRuleExpressions(faTemplatesAndRules));
KieContainer faReportContainer = createContainer(faTemplatesAndRules);
@@ -73,11 +74,16 @@ public void init() {
log.info("Initializing templates and rules for Sales facts. Nr. of Rules : {}", countRuleExpressions(salesTemplatesAndRules));
KieContainer salesContainer = createContainer(salesTemplatesAndRules);
+ log.info("Initializing templates and rules for Movement facts. Nr. of Rules : {}", countRuleExpressions(movementTemplatesAndRules));
+ KieContainer movementContainer = createContainer(movementTemplatesAndRules);
+
+
containers = new EnumMap<>(ContainerType.class);
containers.put(ContainerType.FA_REPORT, faReportContainer);
containers.put(ContainerType.FA_RESPONSE, faRespContainer);
containers.put(ContainerType.FA_QUERY, faQueryContainer);
containers.put(ContainerType.SALES, salesContainer);
+ containers.put(ContainerType.MOVEMENTS, movementContainer);
// To make sure that we have deployed all the templates!
if (!allTemplates.isEmpty()) {
@@ -214,6 +220,18 @@ private List getFaQueryRules(List allTem
return faQueryTemplates;
}
+ private List getMovementRules(List allTemplates) {
+ List movementTemplates = new ArrayList<>();
+ List factTypesList = ContainerType.MOVEMENTS.getFactTypesList();
+ for (TemplateRuleMapDto actualTemplate : allTemplates) {
+ if (factTypesList.contains(actualTemplate.getTemplateType().getType())) {
+ movementTemplates.add(actualTemplate);
+ }
+ }
+ allTemplates.removeAll(movementTemplates);
+ return movementTemplates;
+ }
+
public KieContainer getContainerByType(ContainerType containerType) {
return containers.get(containerType);
}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/mdr/MDRCache.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/mdr/MDRCache.java
index c6271067c..80ee56388 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/mdr/MDRCache.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/mdr/MDRCache.java
@@ -282,6 +282,7 @@ private void overrideBRMessages() {
final List objRapprList = new ArrayList<>();
List brDef = getEntry(MDRAcronymType.FA_BR);
List saleBrDef = getEntry(MDRAcronymType.SALE_BR);
+ List movementDef = getEntry(MDRAcronymType.VP_BR);
// For start up non reachable MDR purposes :)
if (CollectionUtils.isNotEmpty(brDef)) {
objRapprList.addAll(brDef);
@@ -289,6 +290,10 @@ private void overrideBRMessages() {
if (CollectionUtils.isNotEmpty(saleBrDef)) {
objRapprList.addAll(saleBrDef);
}
+ if (CollectionUtils.isNotEmpty(movementDef)) {
+ objRapprList.addAll(movementDef);
+ }
+
objRapprList.removeAll(Collections.singleton(null));
if (CollectionUtils.isEmpty(objRapprList)) {
return;
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/MovementsRulesValidator.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/MovementsRulesValidator.java
index ea19f6ec3..9b1d45089 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/MovementsRulesValidator.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/MovementsRulesValidator.java
@@ -23,6 +23,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.service.business.CustomRuleDto;
import eu.europa.ec.fisheries.uvms.rules.service.business.MovementFact;
import eu.europa.ec.fisheries.uvms.rules.service.business.RawMovementFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentFact;
import eu.europa.ec.fisheries.uvms.rules.service.exception.RulesServiceException;
import eu.europa.ec.fisheries.uvms.rules.service.mapper.CustomRuleParser;
import org.drools.template.parser.DefaultTemplateContainer;
@@ -172,7 +173,7 @@ public void evaluate(MovementFact fact) {
}
@Lock(LockType.READ)
- public void evaluate(List factList, boolean justToAvoidErasure) {
+ public void evaluate(List factList) {
log.info("Verifying user defined rules");
KieSession ksession = getKieSession();
// TODO : decomment as soon as the "Unexpected global [validationService]" is resolved
@@ -186,7 +187,7 @@ public void evaluate(List factList, boolean justToAvoidErasure) {
@Lock(LockType.READ)
- public void evaluate(List facts) {
+ public void evaluateRawList(List facts) {
KieSession ksession = getKieSession();
ksession.setGlobal(LOGGER_STR, log);
for (RawMovementFact fact : facts) {
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBean.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBean.java
index f4b81f220..c343b9b5c 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBean.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBean.java
@@ -12,6 +12,13 @@
package eu.europa.ec.fisheries.uvms.rules.service.bean.movement;
+import static eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType.MOVEMENT;
+import static eu.europa.ec.fisheries.uvms.movement.model.exception.ErrorCode.MOVEMENT_DUPLICATE_ERROR;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.BusinessObjectType.RECEIVING_MOVEMENT_MSG;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.DATA_FLOW;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.SENDER_RECEIVER;
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.XML;
+
import eu.europa.ec.fisheries.remote.RulesDomainModel;
import eu.europa.ec.fisheries.schema.config.module.v1.SettingsListResponse;
import eu.europa.ec.fisheries.schema.config.types.v1.SettingType;
@@ -49,6 +56,7 @@
import eu.europa.ec.fisheries.schema.rules.movement.v1.MovementSourceType;
import eu.europa.ec.fisheries.schema.rules.movement.v1.RawMovementType;
import eu.europa.ec.fisheries.schema.rules.previous.v1.PreviousReportType;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmListCriteria;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmQuery;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmSearchKey;
@@ -89,9 +97,13 @@
import eu.europa.ec.fisheries.uvms.rules.model.exception.RulesModelMarshallException;
import eu.europa.ec.fisheries.uvms.rules.model.mapper.JAXBMarshaller;
import eu.europa.ec.fisheries.uvms.rules.service.bean.RulePostProcessBean;
+import eu.europa.ec.fisheries.uvms.rules.service.bean.RulesConfigurationCache;
+import eu.europa.ec.fisheries.uvms.rules.service.bean.RulesEngineBean;
+import eu.europa.ec.fisheries.uvms.rules.service.bean.RulesExchangeServiceBean;
import eu.europa.ec.fisheries.uvms.rules.service.bean.asset.client.impl.AssetClientBean;
import eu.europa.ec.fisheries.uvms.rules.service.bean.mdr.MDRCache;
import eu.europa.ec.fisheries.uvms.rules.service.business.*;
+import eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType;
import eu.europa.ec.fisheries.uvms.rules.service.constants.MDRAcronymType;
import eu.europa.ec.fisheries.uvms.rules.service.constants.Rule9998Or9999ErrorType;
import eu.europa.ec.fisheries.uvms.rules.service.constants.ServiceConstants;
@@ -101,6 +113,7 @@
import eu.europa.ec.fisheries.uvms.rules.service.event.TicketUpdateEvent;
import eu.europa.ec.fisheries.uvms.rules.service.exception.InputArgumentException;
import eu.europa.ec.fisheries.uvms.rules.service.exception.RulesServiceException;
+import eu.europa.ec.fisheries.uvms.rules.service.exception.RulesValidationException;
import eu.europa.ec.fisheries.uvms.rules.service.mapper.*;
import eu.europa.ec.fisheries.uvms.user.model.mapper.UserModuleRequestMapper;
import eu.europa.ec.fisheries.wsdl.asset.group.AssetGroup;
@@ -116,7 +129,9 @@
import org.apache.commons.lang3.StringUtils;
import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
import un.unece.uncefact.data.standard.mdr.communication.ObjectRepresentation;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
@@ -130,9 +145,6 @@
import java.util.concurrent.*;
import java.util.stream.Collectors;
-import static eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType.MOVEMENT;
-import static eu.europa.ec.fisheries.uvms.movement.model.exception.ErrorCode.MOVEMENT_DUPLICATE_ERROR;
-
@Stateless
@LocalBean
@@ -175,9 +187,18 @@ public class RulesMovementProcessorBean {
@EJB
private RulesAuditProducerBean auditProducer;
+ @EJB
+ private RulesEngineBean rulesEngine;
+
@EJB
private RulePostProcessBean rulePostProcessBean;
+ @EJB
+ private RulesExchangeServiceBean exchangeServiceBean;
+
+ @EJB
+ private RulesConfigurationCache ruleModuleCache;
+
@Inject
private AssetClientBean assetClientBean;
@@ -199,6 +220,8 @@ public class RulesMovementProcessorBean {
private Map mapToMovementType;
+ private RulesFLUXMessageHelper fluxMessageHelper;
+
@Inject
void setMdrCache(MDRCache mdrCache) {
mapToMovementType = new HashMap<>();
@@ -227,6 +250,11 @@ void setMdrCache(MDRCache mdrCache) {
}));
}
+ @PostConstruct
+ public void init() {
+ fluxMessageHelper = new RulesFLUXMessageHelper(ruleModuleCache);
+ }
+
public void sendMovementReport(SendFLUXMovementReportRequest request, String messageGuid) throws RulesServiceException {
log.info("Sending Movement Report to exchange");
try {
@@ -252,16 +280,34 @@ public void setMovementReportReceived(SetFLUXMovementReportRequest request, Stri
sendBatchBackToExchange(request.getLogGuid(), movementReportsList, MovementRefTypeType.ALARM, userName);
return;
}
+
+ Map extraValues = new EnumMap<>(ExtraValueType.class);
+ extraValues.put(SENDER_RECEIVER, request.getSenderOrReceiver());
+ extraValues.put(XML, request.getRequest());
+ extraValues.put(DATA_FLOW, request.getFluxDataFlow());
+ Collection factsResults = rulesEngine.evaluate(RECEIVING_MOVEMENT_MSG,fluxVesselPositionMessage,extraValues,null);
+
+ final String reportId = fluxVesselPositionMessage.getFLUXReportDocument().getIDS().stream()
+ .filter(id -> "UUID".equals(id.getSchemeID()))
+ .map(IDType::getValue)
+ .findFirst()
+ .get();
+ ValidationResult validationResult = rulePostProcessBean.checkAndUpdateValidationResult(factsResults, request.getRequest(), request.getLogGuid(), RawMsgType.MOVEMENT);
+
+ if(validationResult.isError()){
+ exchangeServiceBean.updateExchangeMessage(request.getLogGuid(), fluxMessageHelper.calculateMessageValidationStatus(validationResult));
+ return;
+ }
// Decomment this one and comment the other when validation is working! Still work needs to be done after this!
// processReceivedMovementsAsBatch(movementReportsList, pluginType, userName, request.getLogGuid());
- enrichAndSenMovementsAsBatch(movementReportsList, userName, request.getLogGuid(), request);
+ enrichAndSenMovementsAsBatch(validationResult, movementReportsList, userName, request.getLogGuid(), request, request.getLogGuid());
// Send some response to Movement, if it originated from there (manual movement)
if (MovementSourceType.MANUAL.equals(movementReportsList.get(0).getSource())) {// A person has created a position
ProcessedMovementAck response = MovementModuleResponseMapper.mapProcessedMovementAck(eu.europa.ec.fisheries.schema.movement.common.v1.AcknowledgeTypeType.OK,
messageGuid, "Movement successfully processed");
movOutQueueProducer.sendMessageWithSpecificIds(JAXBMarshaller.marshallJaxBObjectToString(response), movOutQueueProducer.getDestination(), null, messageGuid, messageGuid);
}
- } catch (JAXBException | RulesModelMarshallException | MessageException e) {
+ } catch (JAXBException | RulesModelMarshallException | MessageException | RulesValidationException e) {
log.error("Error while processing received movement", e);
}
}
@@ -276,7 +322,7 @@ public void setMovementReportReceived(SetFLUXMovementReportRequest request, Stri
* @param exchangeLogGuid
* @throws RulesServiceException
*/
- private void enrichAndSenMovementsAsBatch(List rawMovements, String username, String exchangeLogGuid, SetFLUXMovementReportRequest request) throws RulesServiceException {
+ private void enrichAndSenMovementsAsBatch(ValidationResult validationResult, List rawMovements, String username, String exchangeLogGuid, SetFLUXMovementReportRequest request, String reportId) throws RulesServiceException {
try {
// Enrich with MobilTerminal and Assets data. Get Mobile Terminal if it exists.
EnrichedMovementWrapper enrichedWrapper = enrichBatchWithMobileTerminalAndAssets(rawMovements);
@@ -284,18 +330,17 @@ private void enrichAndSenMovementsAsBatch(List rawMovements, St
ExchangeLogStatusTypeType status;
if (movementBatchResponse != null && SimpleResponse.OK.equals(movementBatchResponse.getPermitted())) {
if (SimpleResponse.OK.equals(movementBatchResponse.getResponse())) {
- // Here when ready needs to happen the validation with the list returned from movements! movementBatchResponse.getMovements();
- status = ExchangeLogStatusTypeType.SUCCESSFUL;
+ status = ExchangeLogStatusTypeType.fromValue(fluxMessageHelper.calculateMessageValidationStatus(validationResult).value());
} else {
status = ExchangeLogStatusTypeType.FAILED;
}
} else {
status = ExchangeLogStatusTypeType.FAILED;
- updateValidationResultOnPermissionDenied(JAXBUtils.marshallJaxBObjectToString(movementBatchResponse), request, Rule9998Or9999ErrorType.PERMISSION_DENIED);
+ updateValidationResultOnPermissionDenied(reportId, request, Rule9998Or9999ErrorType.PERMISSION_DENIED);
}
sendBatchBackToExchange(exchangeLogGuid, rawMovements, MovementRefTypeType.MOVEMENT, username);
updateRequestMessageStatusInExchange(exchangeLogGuid, status);
- } catch (MessageException | MobileTerminalModelMapperException | MobileTerminalUnmarshallException | JMSException | AssetModelMapperException | JAXBException e) {
+ } catch (MessageException | MobileTerminalModelMapperException | MobileTerminalUnmarshallException | JMSException | AssetModelMapperException | RulesModelException e) {
throw new RulesServiceException(e.getMessage(), e);
}
}
@@ -306,12 +351,12 @@ private void processReceivedMovementsAsBatch(List rawMovements,
EnrichedMovementWrapper enrichedWrapper = enrichBatchWithMobileTerminalAndAssets(rawMovements);
List rawMovementFactList = RawMovementFactMapper.mapRawMovementFacts(rawMovements, enrichedWrapper.getMobileTerminalList(),
enrichedWrapper.getAssetList(), pluginType);
- movementValidator.evaluate(rawMovementFactList);
+ movementValidator.evaluateRawList(rawMovementFactList);
if (allFactsAreOk(rawMovementFactList)) { // For now it is always OK
// The collectMovementData actually is the method that sends the movements list to Movements module to be saved!
List movementFactList = collectBatchMovementData(enrichedWrapper.getMobileTerminalList(), enrichedWrapper.getAssetList(), rawMovements, username);
log.info(" Validating movement from Movement Module");
- movementValidator.evaluate(movementFactList, true);
+ movementValidator.evaluate(movementFactList);
// Tell Exchange that a movement Batch was persisted in Movement
ExchangeLogStatusTypeType status;
if (CollectionUtils.isNotEmpty(movementFactList)) {
@@ -387,14 +432,7 @@ private List collectConnectIds(List mobileTerminals)
}
private boolean allFactsAreOk(List rawMovementFactList) {
- boolean areAllOk = true;
- for (RawMovementFact movementFact : rawMovementFactList) {
- if (movementFact == null || !movementFact.isOk()) {
- areAllOk = false;
- break;
- }
- }
- return areAllOk;
+ return rawMovementFactList.stream().allMatch(movementFact -> movementFact != null && movementFact.isOk());
}
private List getMobileTerminalByRawMovementsBatch(List rawMovements) throws MessageException, MobileTerminalModelMapperException, MobileTerminalUnmarshallException, JMSException {
@@ -840,15 +878,19 @@ public List call() {
}
// Todo ; When possible remove loop!
- private List collectBatchMovementData(List mobileTerminal, List asset, List rawMovement, String username) {
+ private List collectBatchMovementData(List mobileTerminal, List asset, List rawMovement, String username) throws MessageException {
List movFactList = new ArrayList<>();
int index = 0;
for (RawMovementType rawMovementType : rawMovement) {
try {
movFactList.add(collectMovementData(mobileTerminal.get(index), asset.get(index), rawMovementType, username));
- } catch (ExecutionException | InterruptedException | RulesServiceException e) {
- movFactList.add(null);
+ }
+ catch (InterruptedException e) {
Thread.currentThread().interrupt();
+ throw new MessageException("Thread interrupted...",e);
+ }
+ catch (ExecutionException | RulesServiceException e) {
+ movFactList.add(null);
}
}
return movFactList;
@@ -1610,20 +1652,19 @@ private void updateRequestMessageStatusInExchange(String logGuid, ExchangeLogSta
}
}
- private void updateValidationResultOnPermissionDenied(String rawMessage, RulesBaseRequest request, Rule9998Or9999ErrorType type) {
+ private void updateValidationResultOnPermissionDenied(String reportId, SetFLUXMovementReportRequest request, Rule9998Or9999ErrorType type) throws RulesModelException {
if (request == null || type == null) {
log.error("Could not send FLUXResponseMessage. Request is null or Rule9998Or9999ErrorType not provided.");
return;
}
- RuleError ruleWarning;
+ RuleError ruleError;
if (Rule9998Or9999ErrorType.EMPTY_REPORT.equals(type)) {
- ruleWarning = new RuleError(ServiceConstants.EMPTY_REPORT_RULE, ServiceConstants.EMPTY_REPORT_RULE_MESSAGE, "L03", Collections.singletonList(null));
+ ruleError = new RuleError(ServiceConstants.EMPTY_REPORT_RULE, ServiceConstants.EMPTY_REPORT_RULE_MESSAGE, "L03", Collections.singletonList(null));
} else {
- ruleWarning = new RuleError(ServiceConstants.PERMISSION_DENIED_RULE, ServiceConstants.PERMISSION_DENIED_RULE_MESSAGE, "L00", Collections.singletonList(null));
+ ruleError = new RuleError(ServiceConstants.PERMISSION_DENIED_RULE, ServiceConstants.PERMISSION_DENIED_RULE_MESSAGE, "L00", Collections.singletonList(null));
}
+ ruleError.setXpaths(Collections.singletonList("(//*[local-name()='FLUXVesselPositionMessage']//*[local-name()='FLUXReportDocument'])[1]//*[local-name()='ID']"));
- ValidationResult validationResultDto = rulePostProcessBean.checkAndUpdateValidationResultForGeneralBusinessRules(ruleWarning, rawMessage, request.getLogGuid(), MOVEMENT, request.getDate());
- validationResultDto.setError(true);
- validationResultDto.setOk(false);
+ rulePostProcessBean.createOrUpdateValidationResult(reportId, request.getRequest(), MOVEMENT, ruleError);
}
}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocOwnerFluxPartyIdFact.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocOwnerFluxPartyIdFact.java
new file mode 100644
index 000000000..406c1bd69
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocOwnerFluxPartyIdFact.java
@@ -0,0 +1,23 @@
+package eu.europa.ec.fisheries.uvms.rules.service.business.fact;
+
+import eu.europa.ec.fisheries.schema.rules.template.v1.FactType;
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import lombok.Data;
+import org.joda.time.DateTime;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+
+@Data
+public class MovementReportDocOwnerFluxPartyIdFact extends AbstractFact {
+
+ private IDType id;
+ private DateTime creationDateTime;
+
+ public boolean hasValidSchemeID(IDType id, String schemeID) {
+ return schemeID.equals(id.getSchemeID());
+ }
+
+ @Override
+ public void setFactType() {
+ this.factType = FactType.MOVEMENT_REPORT_DOC_OWNER_FLUX_PARTY_ID;
+ }
+}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentFact.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentFact.java
new file mode 100644
index 000000000..7e7afcedc
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentFact.java
@@ -0,0 +1,105 @@
+/*
+Developed by the European Commission - Directorate General for Maritime Affairs and Fisheries @ European Union, 2015-2016.
+
+This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The IFDM Suite is free software: you can redistribute it
+and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of
+the License, or any later version. The IFDM Suite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+details. You should have received a copy of the GNU General Public License along with the IFDM Suite. If not, see .
+
+*/
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.fact;
+
+import java.time.format.DateTimeFormatter;
+import java.time.format.DateTimeFormatterBuilder;
+import java.time.format.DateTimeParseException;
+import java.time.temporal.ChronoField;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+
+import eu.europa.ec.fisheries.schema.rules.template.v1.FactType;
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import lombok.Data;
+import org.joda.time.DateTime;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.FLUXPartyType;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.VesselCountryType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.CodeType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+
+@Data
+public class MovementReportDocumentFact extends AbstractFact {
+
+ private boolean ok = true;
+ private Date creationDateTime;
+ private String creationDateTimeString;
+ private List ids;
+ private CodeType purposeCode;
+ private FLUXPartyType ownerFLUXParty;
+ private VesselCountryType registrationVesselCountry;
+ private IDType registrationVesselCountryIdType;
+ private DateTime dateTime;
+
+
+ public boolean containsTypesOfIdXTimes(List ids,String schemaType,int count){
+
+ int counter = 0;
+ for(IDType idType:ids){
+
+ if(schemaType.equals(idType.getSchemeID())){
+ counter ++;
+ }
+ }
+
+ return counter == count;
+ }
+
+ public boolean hasValidCreationDateTime(String creationDateTimeString) {
+ DateTimeFormatter formatter = new DateTimeFormatterBuilder()
+ .parseStrict()
+ .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
+ .optionalStart()
+ .appendFraction(ChronoField.MICRO_OF_SECOND, 1, 6, true)
+ .optionalEnd()
+ .appendLiteral('Z')//timezone must always be utc, thus the literal Z
+ .parseStrict().toFormatter();
+ try {
+ formatter.parse(creationDateTimeString);
+ } catch (DateTimeParseException e) {
+ return false;
+ }
+ return true;
+ }
+
+ public boolean isDateInThePast(Date creationDateTime){
+
+ Calendar serverDate = Calendar.getInstance();
+ long t= serverDate.getTimeInMillis();
+ Date startDate = new Date(t - 10 * 60000);
+ new Date();
+
+ return creationDateTime.after(startDate) && creationDateTime.before(serverDate.getTime());
+ }
+
+ public boolean hasValidPurposeCodeListId(CodeType purposeCode, String defaultValue) {
+ return defaultValue.equals(purposeCode.getListID());
+ }
+
+ public boolean hasValidPurposeCodeValue(CodeType purposeCode, String defaultValue) {
+ return defaultValue.equals(purposeCode.getValue());
+ }
+
+ public boolean hasValidSchemeId(String schemeId, String expectedValue) {
+ return schemeId != null && !schemeId.isEmpty() && expectedValue.equals(schemeId);
+ }
+
+ public boolean hasValidIdType(IDType idType) {
+ return idType != null && idType.getValue() != null && !idType.getValue().isEmpty();
+ }
+
+ @Override
+ public void setFactType() {
+ this.factType = FactType.MOVEMENT_REPORT_DOCUMENT;
+ }
+}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentIdFact.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentIdFact.java
new file mode 100644
index 000000000..e8bd26f3f
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentIdFact.java
@@ -0,0 +1,33 @@
+package eu.europa.ec.fisheries.uvms.rules.service.business.fact;
+
+import eu.europa.ec.fisheries.schema.rules.template.v1.FactType;
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import lombok.Data;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+
+
+@Data
+public class MovementReportDocumentIdFact extends AbstractFact {
+
+ private IDType id;
+
+ public boolean uuidValidateRegex(IDType id){
+ if(id == null){
+ return true;
+ }
+
+ String UUID_PATTERN = "^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$";
+
+ if("UUID".equals(id.getSchemeID()) && id.getValue() != null){
+ return id.getValue().matches(UUID_PATTERN);
+ }
+
+
+ return true;
+ }
+
+ @Override
+ public void setFactType() {
+ this.factType = FactType.MOVEMENT_REPORT_DOCUMENT_ID;
+ }
+}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementVesselTransportMeansIdFact.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementVesselTransportMeansIdFact.java
new file mode 100644
index 000000000..d3dbd1c23
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementVesselTransportMeansIdFact.java
@@ -0,0 +1,19 @@
+package eu.europa.ec.fisheries.uvms.rules.service.business.fact;
+
+import eu.europa.ec.fisheries.schema.rules.template.v1.FactType;
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import lombok.Data;
+import org.joda.time.DateTime;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+
+@Data
+public class MovementVesselTransportMeansIdFact extends AbstractFact {
+
+ private IDType id;
+ private DateTime creationDateTime;
+
+ @Override
+ public void setFactType() {
+ this.factType = FactType.MOVEMENT_VESSEL_TRANSPORT_MEANS_ID;
+ }
+}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGenerator.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGenerator.java
new file mode 100644
index 000000000..29e8c48ab
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGenerator.java
@@ -0,0 +1,78 @@
+/*
+Developed by the European Commission - Directorate General for Maritime Affairs and Fisheries @ European Union, 2015-2016.
+
+This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The IFDM Suite is free software: you can redistribute it
+and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of
+the License, or any later version. The IFDM Suite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+details. You should have received a copy of the GNU General Public License along with the IFDM Suite. If not, see .
+
+*/
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.generator;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.MessageType;
+import eu.europa.ec.fisheries.uvms.rules.service.exception.RulesValidationException;
+import eu.europa.ec.fisheries.uvms.rules.service.mapper.fact.MovementReportDocumentFactMapper;
+import eu.europa.ec.fisheries.uvms.rules.service.mapper.xpath.util.XPathStringWrapper;
+import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.FLUXReportDocumentType;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.VesselTransportMeansType;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._20.VesselTransportMeans;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static eu.europa.ec.fisheries.uvms.rules.service.config.ExtraValueType.DATA_FLOW;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.MOVEMENT_REPORT_DOCUMENT;
+
+public class MovementFactGenerator extends AbstractGenerator {
+
+ private MovementReportDocumentFactMapper movementReportDocumentFactMapper;
+ private XPathStringWrapper xPathUtil;
+ private FLUXVesselPositionMessage vesselPositionMessage;
+
+ public MovementFactGenerator(MessageType messageType) {
+ super(messageType);
+ xPathUtil = new XPathStringWrapper();
+ movementReportDocumentFactMapper = new MovementReportDocumentFactMapper(xPathUtil);
+ }
+
+ public MovementFactGenerator(MessageType messageType,XPathStringWrapper xPathUtil, MovementReportDocumentFactMapper movementReportDocumentFactMapper) {
+ super(messageType);
+ this.xPathUtil = xPathUtil;
+ this.movementReportDocumentFactMapper = movementReportDocumentFactMapper;
+ }
+
+ public MovementFactGenerator() {
+ super(MessageType.PUSH);
+ }
+
+ @Override
+ public List generateAllFacts() {
+ List facts = new ArrayList<>();
+ FLUXReportDocumentType fluxReportDocument = vesselPositionMessage.getFLUXReportDocument();
+
+ if (fluxReportDocument != null) {
+ facts.add(movementReportDocumentFactMapper.generateFactForMovementReportDocument(vesselPositionMessage));
+ facts.addAll(movementReportDocumentFactMapper.generateFactForMovementReportDocumentId(vesselPositionMessage));
+ facts.addAll(movementReportDocumentFactMapper.generateFactForMovementReportDocOwnerFluxPartyId(vesselPositionMessage));
+ facts.addAll(movementReportDocumentFactMapper.generateFactForMovementVesselTransportMeansId(vesselPositionMessage));
+ }
+
+ String df = (String) extraValueMap.get(DATA_FLOW);
+ facts.forEach(fact -> fact.setMessageDataFlow(df));
+ xPathUtil.clear();
+ return facts;
+ }
+
+ @Override
+ public void setBusinessObjectMessage(Object businessObject) throws RulesValidationException {
+
+ if (!(businessObject instanceof FLUXVesselPositionMessage)) {
+ throw new RulesValidationException("Business object does not match required type");
+ }
+ this.vesselPositionMessage = (FLUXVesselPositionMessage) businessObject;
+ }
+}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/DrtPathHelper.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/DrtPathHelper.java
index 4c9697add..fbb8663d2 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/DrtPathHelper.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/DrtPathHelper.java
@@ -34,6 +34,10 @@ public enum DrtPathHelper {
FISHING_ACTIVITY("/templates/FishingActivity.drt"),
FA_QUERY("/templates/FaQuery.drt"),
FA_QUERY_PARAMETER("/templates/FaQueryParameter.drt"),
+ MOVEMENT_REPORT_DOCUMENT("/templates/MovementReportDocument.drt"),
+ MOVEMENT_REPORT_DOCUMENT_ID("/templates/MovementReportDocumentId.drt"),
+ MOVEMENT_REPORT_DOC_OWNER_FLUX_PARTY_ID("/templates/MovementReportDocOwnerFluxPartyId.drt"),
+ MOVEMENT_VESSEL_TRANSPORT_MEANS_ID("/templates/MovementVesselTransportMeansId.drt"),
FA_RELOCATION("/templates/FaRelocation.drt"),
FA_RESPONSE("/templates/FaResponse.drt"),
FA_TRANSHIPMENT("/templates/FaTranshipment.drt"),
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/RuleApplicabilityChecker.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/RuleApplicabilityChecker.java
index 000afefe1..4485fb37d 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/RuleApplicabilityChecker.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/helper/RuleApplicabilityChecker.java
@@ -76,6 +76,7 @@ && isDateInRange(messageCreationDate, faBrForBrIdAndContext.getStartDate(), faBr
* @return
*/
public boolean isApplicable(String thisRulesBrId, String ruleContext, String messageDataFlow, DateTime messageCreationDate, MDRCacheRuleService mdrService) {
+
String msgContext = mdrService.findContextForDf(messageDataFlow);
if (StringUtils.isEmpty(msgContext)) {
return false;
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/config/BusinessObjectType.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/config/BusinessObjectType.java
index 3aba6f994..e87807e7f 100755
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/config/BusinessObjectType.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/config/BusinessObjectType.java
@@ -26,5 +26,6 @@ public enum BusinessObjectType {
RECEIVING_FA_RESPONSE_MSG,
FLUX_SALES_REPORT_MSG,
FLUX_SALES_RESPONSE_MSG,
- FLUX_SALES_QUERY_MSG
+ FLUX_SALES_QUERY_MSG,
+ RECEIVING_MOVEMENT_MSG
}
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/MDRAcronymType.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/MDRAcronymType.java
index ee4a476b1..e4ddb86aa 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/MDRAcronymType.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/MDRAcronymType.java
@@ -87,7 +87,9 @@ public enum MDRAcronymType {
TARGET_SPECIES_GROUP("TARGET_SPECIES_GROUP"),
GENDER("GENDER"),
FA_BR_DEF("FA_BR_DEF"),
- SALE_BR_DEF("SALE_BR_DEF");
+ SALE_BR_DEF("SALE_BR_DEF"),
+ VP_BR("VP_BR"),
+ VP_BR_DEF("VP_BR_DEF");
private final String value;
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/XPathConstants.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/XPathConstants.java
index e614b8c36..a65bb751b 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/XPathConstants.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/XPathConstants.java
@@ -21,6 +21,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
public class XPathConstants {
public static final String FLUXFA_REPORT_MESSAGE = "FLUXFAReportMessage";
+ public static final String MOVEMENT_REPORT_DOCUMENT = "FLUXVesselPositionMessage";
public static final String FLUXFA_QUERY_MESSAGE = "FLUXFAQueryMessage";
public static final String FA_REPORT_DOCUMENT = "FAReportDocument";
public static final String SPECIFIED_FISHING_ACTIVITY = "SpecifiedFishingActivity";
@@ -38,6 +39,8 @@ public class XPathConstants {
public static final String RELATED_FLUX_REPORT_DOCUMENT = "RelatedFLUXReportDocument";
public static final String TYPE_CODE = "TypeCode";
public static final String RELATED_REPORT_ID = "RelatedReportID";
+ public static final String VESSEL_TRANSPORT_MEANS = "VesselTransportMeans";
+ public static final String VESSEL_TRANSPORT_MEANS_ID = "VesselTransportMeansId";
public static final String SPECIFIED_VESSEL_TRANSPORT_MEANS = "SpecifiedVesselTransportMeans";
public static final String RELATED_FISHING_ACTIVITY = "RelatedFishingActivity";
public static final String SPECIFIED_DELIMITED_PERIOD = "SpecifiedDelimitedPeriod";
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/ActivityFactMapper.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/ActivityFactMapper.java
index 9f9dfd6e1..ff9207454 100644
--- a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/ActivityFactMapper.java
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/ActivityFactMapper.java
@@ -324,7 +324,7 @@ public FishingActivityFact generateFishingActivityFact(FishingActivity fishingAc
fishingActivityFact.setFaReportDocumentTypeCode(mapToCodeType(faReportDocument != null ? faReportDocument.getTypeCode() : null));
fishingActivityFact.setFaReportDocuments(fluxfaReportMessage.getFAReportDocuments());
fishingActivityFact.setFaReportDocument(faReportDocument);
- fishingActivityFact.setPurposeCode(mapToCodeType(faReportDocument.getRelatedFLUXReportDocument() == null ? null:faReportDocument.getRelatedFLUXReportDocument().getPurposeCode()));
+ fishingActivityFact.setPurposeCode(mapToCodeType(faReportDocument.getRelatedFLUXReportDocument() == null ? null : faReportDocument.getRelatedFLUXReportDocument().getPurposeCode()));
String partialXpath = xPathUtil.getValue();
diff --git a/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapper.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapper.java
new file mode 100644
index 000000000..e9cf509d7
--- /dev/null
+++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapper.java
@@ -0,0 +1,205 @@
+/*
+Developed by the European Commission - Directorate General for Maritime Affairs and Fisheries @ European Union, 2015-2016.
+
+This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The IFDM Suite is free software: you can redistribute it
+and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of
+the License, or any later version. The IFDM Suite is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+details. You should have received a copy of the GNU General Public License along with the IFDM Suite. If not, see .
+
+*/
+
+package eu.europa.ec.fisheries.uvms.rules.service.mapper.fact;
+
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.CREATION_DATE_TIME;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.FLUX_REPORT_DOCUMENT;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.MOVEMENT_REPORT_DOCUMENT;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.OWNER_FLUX_PARTY;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.PURPOSE_CODE;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.REGISTRATION_VESSEL_COUNTRY;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.VESSEL_TRANSPORT_MEANS;
+import static eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants.VESSEL_TRANSPORT_MEANS_ID;
+
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Optional;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocOwnerFluxPartyIdFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentIdFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementVesselTransportMeansIdFact;
+import eu.europa.ec.fisheries.uvms.rules.service.constants.XPathConstants;
+import eu.europa.ec.fisheries.uvms.rules.service.mapper.xpath.util.XPathStringWrapper;
+import lombok.extern.slf4j.Slf4j;
+import org.joda.time.DateTime;
+import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.CodeType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.DateTimeType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
+
+@Slf4j
+public class MovementReportDocumentFactMapper {
+
+ private XPathStringWrapper xPathUtil;
+ public static final String ID = "id";
+
+
+ public MovementReportDocumentFactMapper() {
+ xPathUtil = new XPathStringWrapper();
+ }
+ public MovementReportDocumentFactMapper(XPathStringWrapper strUtil1) {
+ this.xPathUtil = strUtil1;
+ }
+
+ public MovementReportDocumentFact generateFactForMovementReportDocument(FLUXVesselPositionMessage vesselPositionMessage){
+
+ if(vesselPositionMessage == null){
+ xPathUtil.clear();
+ return null;
+ }
+
+ MovementReportDocumentFact fact = new MovementReportDocumentFact();
+ String partialXpath = xPathUtil.append(MOVEMENT_REPORT_DOCUMENT).getValue();
+
+ DateTimeType creationDateTime = vesselPositionMessage.getFLUXReportDocument().getCreationDateTime();
+ fact.setCreationDateTimeString(dateTimeAsString(creationDateTime));
+ fact.setCreationDateTime(getDate(creationDateTime));
+ xPathUtil.appendWithoutWrapping(partialXpath).append(FLUX_REPORT_DOCUMENT, XPathConstants.CREATION_DATE_TIME).storeInRepo(fact, CREATION_DATE_TIME);
+ fact.setIds(vesselPositionMessage.getFLUXReportDocument().getIDS());
+ xPathUtil.appendWithoutWrapping(partialXpath).append(FLUX_REPORT_DOCUMENT, XPathConstants.ID).storeInRepo(fact, "id");
+ CodeType purposeCode = vesselPositionMessage.getFLUXReportDocument().getPurposeCode();
+ fact.setPurposeCode(purposeCode);
+ xPathUtil.appendWithoutWrapping(partialXpath).append(FLUX_REPORT_DOCUMENT, PURPOSE_CODE).storeInRepo(fact, PURPOSE_CODE);
+ fact.setOwnerFLUXParty(vesselPositionMessage.getFLUXReportDocument().getOwnerFLUXParty());
+ xPathUtil.appendWithoutWrapping(partialXpath).append(FLUX_REPORT_DOCUMENT, OWNER_FLUX_PARTY).storeInRepo(fact, OWNER_FLUX_PARTY);
+
+ Optional.ofNullable(vesselPositionMessage.getVesselTransportMeans()).ifPresent(vtm -> {
+ fact.setRegistrationVesselCountry(vesselPositionMessage.getVesselTransportMeans().getRegistrationVesselCountry());
+ xPathUtil.appendWithoutWrapping(partialXpath).append(VESSEL_TRANSPORT_MEANS, REGISTRATION_VESSEL_COUNTRY).storeInRepo(fact, REGISTRATION_VESSEL_COUNTRY);
+
+ Optional.ofNullable(vtm.getRegistrationVesselCountry()).ifPresent(rvc -> {
+ fact.setRegistrationVesselCountryIdType(rvc.getID());
+ xPathUtil.appendWithoutWrapping(partialXpath).append(REGISTRATION_VESSEL_COUNTRY, XPathConstants.ID).storeInRepo(fact, "registrationVesselCountryId");
+ });
+ });
+ fact.setDateTime(new DateTime(getDate(creationDateTime)));
+
+ return fact;
+ }
+
+ public List generateFactForMovementReportDocumentId(FLUXVesselPositionMessage vesselPositionMessage){
+
+ List factList = new ArrayList<>();
+
+ if(vesselPositionMessage == null || vesselPositionMessage.getFLUXReportDocument() == null || vesselPositionMessage.getFLUXReportDocument().getIDS() == null || vesselPositionMessage.getFLUXReportDocument().getIDS().isEmpty()){
+ xPathUtil.clear();
+ return factList;
+ }
+
+ String partialXpath = xPathUtil.append(MOVEMENT_REPORT_DOCUMENT).getValue();
+
+ List ids = vesselPositionMessage.getFLUXReportDocument().getIDS();
+ int index = 1;
+ for(IDType idType: ids){
+ MovementReportDocumentIdFact fact = new MovementReportDocumentIdFact();
+ fact.setId(idType);
+ xPathUtil.appendWithoutWrapping(partialXpath).append(FLUX_REPORT_DOCUMENT).appendWithIndex(XPathConstants.ID,index).storeInRepo(fact, "id");
+ factList.add(fact);
+ index ++;
+ }
+ return factList;
+ }
+
+ public List generateFactForMovementReportDocOwnerFluxPartyId(FLUXVesselPositionMessage vesselPositionMessage) {
+ List factList = new ArrayList<>();
+
+ if(vesselPositionMessage == null || vesselPositionMessage.getFLUXReportDocument() == null || vesselPositionMessage.getFLUXReportDocument().getOwnerFLUXParty() == null || vesselPositionMessage.getFLUXReportDocument().getOwnerFLUXParty().getIDS().isEmpty()){
+ xPathUtil.clear();
+ return factList;
+ }
+
+ String partialXpath = xPathUtil.append(MOVEMENT_REPORT_DOCUMENT).append(FLUX_REPORT_DOCUMENT).append(OWNER_FLUX_PARTY).getValue();
+ List ids = vesselPositionMessage.getFLUXReportDocument().getOwnerFLUXParty().getIDS();
+ Date creationDate = getDate(vesselPositionMessage.getFLUXReportDocument().getCreationDateTime());
+ int index = 1;
+ for(IDType idType: ids){
+ MovementReportDocOwnerFluxPartyIdFact fact = new MovementReportDocOwnerFluxPartyIdFact();
+ fact.setId(idType);
+ fact.setCreationDateTime(new DateTime(creationDate));
+ xPathUtil.appendWithoutWrapping(partialXpath).appendWithIndex(XPathConstants.ID,index).storeInRepo(fact, "ownerFluxPartyId");
+ factList.add(fact);
+ index ++;
+ }
+ return factList;
+ }
+
+ public List generateFactForMovementVesselTransportMeansId(FLUXVesselPositionMessage vesselPositionMessage) {
+ List factList = new ArrayList<>();
+
+ if(vesselPositionMessage == null || vesselPositionMessage.getVesselTransportMeans() == null || vesselPositionMessage.getVesselTransportMeans().getIDS().isEmpty()){
+ xPathUtil.clear();
+ return null;
+ }
+
+ String partialXpath = xPathUtil.append(MOVEMENT_REPORT_DOCUMENT).append(VESSEL_TRANSPORT_MEANS).getValue();
+ List ids = vesselPositionMessage.getVesselTransportMeans().getIDS();
+ Date creationDate = getDate(vesselPositionMessage.getFLUXReportDocument().getCreationDateTime());
+ int index = 1;
+ for(IDType idType: ids){
+ MovementVesselTransportMeansIdFact fact = new MovementVesselTransportMeansIdFact();
+ fact.setId(idType);
+ fact.setCreationDateTime(new DateTime(creationDate));
+ xPathUtil.appendWithoutWrapping(partialXpath).appendWithIndex(XPathConstants.ID,index).storeInRepo(fact, VESSEL_TRANSPORT_MEANS_ID);
+ factList.add(fact);
+ index ++;
+ }
+ return factList;
+ }
+
+ public static MovementReportDocumentFact mapToMovementReportDocumentFact(FLUXVesselPositionMessage vesselPositionMessage){
+
+ if(vesselPositionMessage == null || vesselPositionMessage.getFLUXReportDocument() == null){
+ throw new IllegalArgumentException("FLUXVesselPositionMessage and FLUXReportDocument cannot be null");
+ }
+
+ MovementReportDocumentFact fact = new MovementReportDocumentFact();
+ DateTimeType creationDateTime = vesselPositionMessage.getFLUXReportDocument().getCreationDateTime();
+ fact.setCreationDateTime(getDate(creationDateTime));
+ fact.setCreationDateTimeString(dateTimeAsString(creationDateTime));
+ return fact;
+ }
+
+ private static String dateTimeAsString(DateTimeType dateTimeType) {
+ String dateAsString = null;
+
+ if (dateTimeType != null) {
+ try {
+ if (dateTimeType.getDateTime() != null) {
+ dateAsString = dateTimeType.getDateTime().toString();
+ }
+ } catch (Exception e) {
+ log.debug("Error while trying to parse dateTimeType", e);
+ }
+ }
+ return dateAsString;
+ }
+
+ private static Date getDate(DateTimeType dateTimeType) {
+ Date date = null;
+ if (dateTimeType != null) {
+ try {
+ if (dateTimeType.getDateTime() != null) {
+ date = dateTimeType.getDateTime().toGregorianCalendar().getTime();
+ }
+ } catch (Exception e) {
+ log.debug("Error while trying to parse dateTimeType", e);
+ }
+ }
+
+ return date;
+ }
+
+
+
+}
diff --git a/service/src/main/resources/templates/MovementReportDocOwnerFluxPartyId.drt b/service/src/main/resources/templates/MovementReportDocOwnerFluxPartyId.drt
new file mode 100644
index 000000000..42e12cb56
--- /dev/null
+++ b/service/src/main/resources/templates/MovementReportDocOwnerFluxPartyId.drt
@@ -0,0 +1,34 @@
+template header
+
+tname
+expression
+brid
+rulemsg
+type
+level
+propertyNames
+context
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.activity;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocOwnerFluxPartyIdFact;
+import java.util.Arrays;
+global eu.europa.ec.fisheries.uvms.rules.service.business.helper.RuleApplicabilityChecker appliChecker;
+global eu.europa.ec.fisheries.uvms.rules.service.MDRCacheRuleService mdrService;
+
+
+template "@{tname}"
+
+rule "Movement Report Document Owner Flux Party Id @{tname} - @{brid} - Context : @{context}"
+
+when
+
+ $fact : MovementReportDocOwnerFluxPartyIdFact((appliChecker.isApplicable("@{brid}", "@{context}", getMessageDataFlow(), getCreationDateOfMessage(), mdrService)) && (@{expression}))
+
+then
+ $fact.setOk(false);
+ $fact.addWarningOrError(mdrService.getErrorTypeStrForForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), mdrService.getErrorMessageForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), "@{brid}", "@{level}", "@{propertyNames}");
+
+end
+
+end template
\ No newline at end of file
diff --git a/service/src/main/resources/templates/MovementReportDocument.drt b/service/src/main/resources/templates/MovementReportDocument.drt
new file mode 100644
index 000000000..fe104b816
--- /dev/null
+++ b/service/src/main/resources/templates/MovementReportDocument.drt
@@ -0,0 +1,34 @@
+template header
+
+tname
+expression
+brid
+rulemsg
+type
+level
+propertyNames
+context
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.activity;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentFact;
+import java.util.Arrays;
+global eu.europa.ec.fisheries.uvms.rules.service.business.helper.RuleApplicabilityChecker appliChecker;
+global eu.europa.ec.fisheries.uvms.rules.service.MDRCacheRuleService mdrService;
+
+
+template "@{tname}"
+
+rule "Movement Report Document @{tname} - @{brid} - Context : @{context}"
+
+when
+
+ $fact : MovementReportDocumentFact((appliChecker.isApplicable("@{brid}", "@{context}", getMessageDataFlow(), getCreationDateOfMessage(), mdrService)) && (@{expression}))
+
+then
+ $fact.setOk(false);
+ $fact.addWarningOrError(mdrService.getErrorTypeStrForForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), mdrService.getErrorMessageForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), "@{brid}", "@{level}", "@{propertyNames}");
+
+end
+
+end template
\ No newline at end of file
diff --git a/service/src/main/resources/templates/MovementReportDocumentId.drt b/service/src/main/resources/templates/MovementReportDocumentId.drt
new file mode 100644
index 000000000..7c37c4d1b
--- /dev/null
+++ b/service/src/main/resources/templates/MovementReportDocumentId.drt
@@ -0,0 +1,34 @@
+template header
+
+tname
+expression
+brid
+rulemsg
+type
+level
+propertyNames
+context
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.activity;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentIdFact;
+import java.util.Arrays;
+global eu.europa.ec.fisheries.uvms.rules.service.business.helper.RuleApplicabilityChecker appliChecker;
+global eu.europa.ec.fisheries.uvms.rules.service.MDRCacheRuleService mdrService;
+
+
+template "@{tname}"
+
+rule "Movement Report Document Id @{tname} - @{brid} - Context : @{context}"
+
+when
+
+ $fact : MovementReportDocumentIdFact((appliChecker.isApplicable("@{brid}", "@{context}", getMessageDataFlow(), getCreationDateOfMessage(), mdrService)) && (@{expression}))
+
+then
+ $fact.setOk(false);
+ $fact.addWarningOrError(mdrService.getErrorTypeStrForForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), mdrService.getErrorMessageForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), "@{brid}", "@{level}", "@{propertyNames}");
+
+end
+
+end template
\ No newline at end of file
diff --git a/service/src/main/resources/templates/MovementVesselTransportMeansId.drt b/service/src/main/resources/templates/MovementVesselTransportMeansId.drt
new file mode 100644
index 000000000..3cf56c60b
--- /dev/null
+++ b/service/src/main/resources/templates/MovementVesselTransportMeansId.drt
@@ -0,0 +1,34 @@
+template header
+
+tname
+expression
+brid
+rulemsg
+type
+level
+propertyNames
+context
+
+package eu.europa.ec.fisheries.uvms.rules.service.business.activity;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementVesselTransportMeansIdFact;
+import java.util.Arrays;
+global eu.europa.ec.fisheries.uvms.rules.service.business.helper.RuleApplicabilityChecker appliChecker;
+global eu.europa.ec.fisheries.uvms.rules.service.MDRCacheRuleService mdrService;
+
+
+template "@{tname}"
+
+rule "Movement Vessel Transport Means Id @{tname} - @{brid} - Context : @{context}"
+
+when
+
+ $fact : MovementVesselTransportMeansIdFact((appliChecker.isApplicable("@{brid}", "@{context}", getMessageDataFlow(), getCreationDateOfMessage(), mdrService)) && (@{expression}))
+
+then
+ $fact.setOk(false);
+ $fact.addWarningOrError(mdrService.getErrorTypeStrForForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), mdrService.getErrorMessageForBrIAndDFAndValidity("@{brid}", "@{context}", $fact.getCreationJavaDateOfMessage()), "@{brid}", "@{level}", "@{propertyNames}");
+
+end
+
+end template
\ No newline at end of file
diff --git a/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBeanTest.java b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBeanTest.java
index 17c7007d7..7b5300d69 100644
--- a/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBeanTest.java
+++ b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/RulesMovementProcessorBeanTest.java
@@ -22,6 +22,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.schema.rules.exchange.v1.PluginType;
import eu.europa.ec.fisheries.schema.rules.module.v1.SetFLUXMovementReportRequest;
import eu.europa.ec.fisheries.schema.rules.previous.v1.PreviousReportType;
+import eu.europa.ec.fisheries.schema.rules.rule.v1.RawMsgType;
import eu.europa.ec.fisheries.schema.rules.search.v1.AlarmQuery;
import eu.europa.ec.fisheries.schema.rules.search.v1.TicketQuery;
import eu.europa.ec.fisheries.schema.rules.source.v1.GetAlarmListByQueryResponse;
@@ -42,8 +43,11 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.model.dto.TicketListResponseDto;
import eu.europa.ec.fisheries.uvms.rules.model.mapper.RulesDataSourceRequestMapper;
import eu.europa.ec.fisheries.uvms.rules.model.mapper.RulesDataSourceResponseMapper;
+import eu.europa.ec.fisheries.uvms.rules.service.bean.RulePostProcessBean;
+import eu.europa.ec.fisheries.uvms.rules.service.bean.RulesEngineBean;
import eu.europa.ec.fisheries.uvms.rules.service.bean.mdr.MDRCache;
import eu.europa.ec.fisheries.uvms.rules.service.business.PreviousReportFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.ValidationResult;
import eu.europa.ec.fisheries.uvms.rules.service.constants.MDRAcronymType;
import eu.europa.ec.fisheries.uvms.rules.service.constants.ServiceConstants;
import org.junit.Before;
@@ -60,9 +64,11 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
import un.unece.uncefact.data.standard.mdr.communication.ColumnDataType;
import un.unece.uncefact.data.standard.mdr.communication.ObjectRepresentation;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.FLUXReportDocumentType;
import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.VesselPositionEventType;
import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.VesselTransportMeansType;
import un.unece.uncefact.data.standard.unqualifieddatatype._18.CodeType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.IDType;
import javax.enterprise.event.Event;
import javax.jms.JMSException;
@@ -89,6 +95,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
public class RulesMovementProcessorBeanTest {
private static final String USERNAME = "USERNAME";
+ private static final String FLUX_REPORT_DOC_UUID = UUID.randomUUID().toString();
@Mock
RulesMessageProducer mockProducer;
@@ -112,6 +119,10 @@ public class RulesMovementProcessorBeanTest {
MDRCache mdrCache;
@Mock
RulesExchangeProducerBean exchangeProducer;
+ @Mock
+ RulesEngineBean rulesEngine;
+ @Mock
+ RulePostProcessBean rulePostProcessBean;
@InjectMocks
RulesMovementProcessorBean rulesMovementProcessorBean;
@@ -546,6 +557,9 @@ public void testSetMovementReportReceived() throws Exception {
setupMobileTerminalConversation();
setupMovementModuleConversation();
String messageGuid = UUID.randomUUID().toString();
+ ValidationResult validationResult = new ValidationResult();
+ validationResult.setError(false);
+ when(rulePostProcessBean.checkAndUpdateValidationResult(any(), anyString(), anyString(), eq(RawMsgType.MOVEMENT))).thenReturn(validationResult);
rulesMovementProcessorBean.setMovementReportReceived(request, messageGuid);
@@ -577,6 +591,12 @@ private void setupFluxVesselPositionMessage(SetFLUXMovementReportRequest request
vesselPositionEvent.setTypeCode(new CodeType());
vesselPositionEvent.getTypeCode().setValue("MANUAL");
vesselTransportMeans.getSpecifiedVesselPositionEvents().add(vesselPositionEvent);
+ FLUXReportDocumentType fluxReportDoc = new FLUXReportDocumentType();
+ final IDType id = new IDType();
+ id.setSchemeID("UUID");
+ id.setValue(FLUX_REPORT_DOC_UUID);
+ fluxReportDoc.getIDS().add(id);
+ fluxVesselPositionMessage.setFLUXReportDocument(fluxReportDoc);
request.setRequest(JAXBUtils.marshallJaxBObjectToString(fluxVesselPositionMessage, "UTF-8", true));
}
diff --git a/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGeneratorTest.java b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGeneratorTest.java
new file mode 100644
index 000000000..e9848a9de
--- /dev/null
+++ b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGeneratorTest.java
@@ -0,0 +1,29 @@
+package eu.europa.ec.fisheries.uvms.rules.service.business.generator;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import eu.europa.ec.fisheries.uvms.rules.service.config.BusinessObjectType;
+import eu.europa.ec.fisheries.uvms.rules.service.exception.RulesValidationException;
+import org.junit.Test;
+import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.FLUXReportDocumentType;
+
+import java.util.HashMap;
+import java.util.List;
+
+import static eu.europa.ec.fisheries.uvms.rules.service.business.MessageType.PUSH;
+import static org.junit.Assert.*;
+
+public class MovementFactGeneratorTest {
+
+ @Test
+ public void testGenerateAllFacts() throws RulesValidationException {
+
+ MovementFactGenerator generator = new MovementFactGenerator(PUSH);
+ FLUXVesselPositionMessage vesselPositionMessage = new FLUXVesselPositionMessage();
+ vesselPositionMessage.setFLUXReportDocument(new FLUXReportDocumentType());
+ generator.setBusinessObjectMessage(vesselPositionMessage);
+ generator.setExtraValueMap(new HashMap<>());
+ List abstractFacts = generator.generateAllFacts();
+ assertEquals(abstractFacts.isEmpty(),false);
+ }
+}
\ No newline at end of file
diff --git a/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapperTest.java b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapperTest.java
new file mode 100644
index 000000000..0208f9a8d
--- /dev/null
+++ b/service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapperTest.java
@@ -0,0 +1,50 @@
+package eu.europa.ec.fisheries.uvms.rules.service.mapper.fact;
+
+import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact;
+import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentFact;
+import org.joda.time.DateTime;
+import org.junit.Test;
+import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.FLUXReportDocumentType;
+import un.unece.uncefact.data.standard.reusableaggregatebusinessinformationentity._18.VesselTransportMeansType;
+import un.unece.uncefact.data.standard.unqualifieddatatype._18.DateTimeType;
+
+import javax.xml.datatype.DatatypeConfigurationException;
+import javax.xml.datatype.DatatypeFactory;
+
+import java.util.Date;
+import java.util.GregorianCalendar;
+
+import static org.junit.Assert.*;
+
+public class MovementReportDocumentFactMapperTest {
+
+ @Test
+ public void testGenerateFactForMovementReportDocumentNULLDates() {
+
+ MovementReportDocumentFactMapper factMapper = new MovementReportDocumentFactMapper();
+ FLUXVesselPositionMessage vesselPositionMessage =new FLUXVesselPositionMessage();
+ vesselPositionMessage.setVesselTransportMeans(new VesselTransportMeansType());
+ vesselPositionMessage.setFLUXReportDocument(new FLUXReportDocumentType());
+ AbstractFact movementReportDocumentFact = factMapper.generateFactForMovementReportDocument(vesselPositionMessage);
+ }
+
+ @Test
+ public void testGenerateFactForMovementReportDocumentNormalDates() throws DatatypeConfigurationException {
+
+ MovementReportDocumentFactMapper factMapper = new MovementReportDocumentFactMapper();
+ FLUXVesselPositionMessage vesselPositionMessage =new FLUXVesselPositionMessage();
+ vesselPositionMessage.setVesselTransportMeans(new VesselTransportMeansType());
+ FLUXReportDocumentType reportDocumentType = new FLUXReportDocumentType();
+ GregorianCalendar calendar = new GregorianCalendar();
+ Date d = new Date();
+ calendar.setTime(d);
+ DateTimeType dateTimeType = new DateTimeType();
+ dateTimeType.setDateTime(DatatypeFactory.newInstance().newXMLGregorianCalendar(calendar));
+ reportDocumentType.setCreationDateTime(dateTimeType);
+ vesselPositionMessage.setFLUXReportDocument(reportDocumentType);
+ MovementReportDocumentFact abstractFact = (MovementReportDocumentFact)factMapper.generateFactForMovementReportDocument(vesselPositionMessage);
+ Date creationDateOfMessage = abstractFact.getCreationDateTime();
+ assertEquals(d,creationDateOfMessage);
+ }
+}
\ No newline at end of file