From fcf562e37473f2f860b6c018433a5d1d59b27878 Mon Sep 17 00:00:00 2001 From: nomikosi <42890529+nomikosi@users.noreply.github.com> Date: Wed, 1 Jul 2020 16:15:42 +0300 Subject: [PATCH] [UNIONVMS-4660] added creationDate rules for movements --- LIQUIBASE/changelog/db-changelog-master.xml | 2 +- .../v3.4/db-changelog-UNIONVMS-4660.xml | 103 ++++++++++++++++++ .../src/main/resources/contract/Template.xsd | 2 + .../rules/service/bean/ContainerType.java | 5 +- .../rules/service/bean/RulesEngineBean.java | 37 ++++++- .../bean/RulesKieContainerInitializer.java | 18 +++ .../movement/MovementsRulesValidator.java | 7 +- .../movement/RulesMovementProcessorBean.java | 75 ++++++++++--- .../fact/MovementReportDocumentFact.java | 31 ++++++ .../generator/MovementFactGenerator.java | 72 ++++++++++++ .../business/helper/DrtPathHelper.java | 1 + .../service/config/BusinessObjectType.java | 3 +- .../service/constants/XPathConstants.java | 1 + .../MovementReportDocumentFactMapper.java | 102 +++++++++++++++++ .../templates/MovementReportDocument.drt | 34 ++++++ .../generator/MovementFactGeneratorTest.java | 29 +++++ .../MovementReportDocumentFactMapperTest.java | 50 +++++++++ 17 files changed, 549 insertions(+), 23 deletions(-) create mode 100644 LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml create mode 100644 service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentFact.java create mode 100644 service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGenerator.java create mode 100644 service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapper.java create mode 100644 service/src/main/resources/templates/MovementReportDocument.drt create mode 100644 service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGeneratorTest.java create mode 100644 service/src/test/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapperTest.java diff --git a/LIQUIBASE/changelog/db-changelog-master.xml b/LIQUIBASE/changelog/db-changelog-master.xml index c7536353b..35897bb8f 100644 --- a/LIQUIBASE/changelog/db-changelog-master.xml +++ b/LIQUIBASE/changelog/db-changelog-master.xml @@ -90,5 +90,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..f1ec73fcc --- /dev/null +++ b/LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml @@ -0,0 +1,103 @@ + + + + + + + + + + + + template_id = 36 + + + + + + + + + + + + + + + + + + + + + + + + + + rule_id = 700 + + + br_id = 'MO-R01-00-0001' + + + + + + + + + + + + + + + + + + + + + + + + + + rule_id = 701 + + + br_id = 'MO-R01-00-0002' + + + + + + + + + + + + + + + + + + + + + + + + + + rule_id = 702 + + + br_id = 'MO-R01-00-0003' + + + + diff --git a/model/src/main/resources/contract/Template.xsd b/model/src/main/resources/contract/Template.xsd index 61604e8d6..e99548f72 100755 --- a/model/src/main/resources/contract/Template.xsd +++ b/model/src/main/resources/contract/Template.xsd @@ -86,6 +86,8 @@ + + \ 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..84fa3c640 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 + ); private final String packageName; private final String containerName; 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/movement/MovementsRulesValidator.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/bean/movement/MovementsRulesValidator.java index 96faef16a..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,9 +187,9 @@ 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); + ksession.setGlobal(LOGGER_STR, log); for (RawMovementFact fact : facts) { ksession.insert(fact); } 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 32e98b6e8..be0601792 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 @@ -48,6 +48,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; @@ -78,6 +79,7 @@ import eu.europa.ec.fisheries.uvms.movement.model.exception.MovementModelException; import eu.europa.ec.fisheries.uvms.movement.model.mapper.MovementModuleRequestMapper; import eu.europa.ec.fisheries.uvms.movement.model.mapper.MovementModuleResponseMapper; +import eu.europa.ec.fisheries.uvms.rules.dao.RulesDao; import eu.europa.ec.fisheries.uvms.rules.message.consumer.RulesResponseConsumer; import eu.europa.ec.fisheries.uvms.rules.message.producer.bean.*; import eu.europa.ec.fisheries.uvms.rules.model.constant.AuditObjectTypeEnum; @@ -89,11 +91,18 @@ import eu.europa.ec.fisheries.uvms.rules.model.exception.RulesModelMapperException; 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.mdr.MDRCache; +import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact; import eu.europa.ec.fisheries.uvms.rules.service.business.MovementFact; import eu.europa.ec.fisheries.uvms.rules.service.business.PreviousReportFact; import eu.europa.ec.fisheries.uvms.rules.service.business.RawMovementFact; import eu.europa.ec.fisheries.uvms.rules.service.business.RulesUtil; +import eu.europa.ec.fisheries.uvms.rules.service.business.ValidationResult; +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.event.AlarmReportCountEvent; import eu.europa.ec.fisheries.uvms.rules.service.event.AlarmReportEvent; @@ -101,6 +110,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,6 +126,7 @@ import un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage; import un.unece.uncefact.data.standard.mdr.communication.ObjectRepresentation; +import javax.annotation.PostConstruct; import javax.ejb.EJB; import javax.ejb.LocalBean; import javax.ejb.Stateless; @@ -130,6 +141,10 @@ import java.util.stream.Collectors; 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; @Stateless @@ -176,6 +191,20 @@ public class RulesMovementProcessorBean { @EJB private RulesAuditProducerBean auditProducer; + @EJB + private RulesEngineBean rulesEngine; + + @EJB + private RulePostProcessBean rulePostProcessBean; + + @EJB + private RulesExchangeServiceBean exchangeServiceBean; + + @EJB + private RulesConfigurationCache ruleModuleCache; + + private RulesFLUXMessageHelper fluxMessageHelper; + @Inject @TicketUpdateEvent private Event ticketUpdateEvent; @@ -232,6 +261,11 @@ public void sendMovementReport(SendFLUXMovementReportRequest request, String mes } } + @PostConstruct + public void init() { + fluxMessageHelper = new RulesFLUXMessageHelper(ruleModuleCache); + } + public void setMovementReportReceived(SetFLUXMovementReportRequest request, String messageGuid) throws RulesServiceException { FLUXVesselPositionMessage fluxVesselPositionMessage; String pluginType = request.getType().name(); @@ -247,9 +281,23 @@ 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); + + ValidationResult validationResult = rulePostProcessBean.checkAndUpdateValidationResult(factsResults, request.getRequest(), String.valueOf(fluxVesselPositionMessage.getFLUXReportDocument().getIDS()), 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! - EnrichedMovementWrapper enrichedWrapper = processReceivedMovementsAsBatch(movementReportsList, pluginType, userName, request.getLogGuid()); -// enrichAndSenMovementsAsBatch(enrichedWrapper, movementReportsList, userName, request.getLogGuid()); +// MovementReportDocumentFact movementReportDocumentFact = MovementReportDocumentFactMapper.mapToMovementReportDocumentFact(fluxVesselPositionMessage); +// EnrichedMovementWrapper enrichedWrapper = processReceivedMovementsAsBatch(movementReportsList, pluginType, userName, request.getLogGuid()); + enrichAndSendMovementsAsBatch(validationResult, movementReportsList, userName, request.getLogGuid()); // enrichAndSenMovementsAsBatch(null, movementReportsList, userName, 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 @@ -257,7 +305,7 @@ public void setMovementReportReceived(SetFLUXMovementReportRequest request, Stri messageGuid, "Movement successfully processed"); movOutQueueProducer.sendMessageWithSpecificIds(JAXBMarshaller.marshallJaxBObjectToString(response), movOutQueueProducer.getDestination(), null, messageGuid, messageGuid); } - } catch (JAXBException | RulesModelMarshallException | MessageException e) { + } catch (JAXBException | MessageException | RulesValidationException | RulesModelMarshallException e) { log.error("Error while processing received movement", e); } } @@ -272,15 +320,15 @@ public void setMovementReportReceived(SetFLUXMovementReportRequest request, Stri * @param exchangeLogGuid * @throws RulesServiceException */ - private void enrichAndSenMovementsAsBatch(EnrichedMovementWrapper enrichedWrapper1, List rawMovements, String username, String exchangeLogGuid) throws RulesServiceException { + private void enrichAndSendMovementsAsBatch(ValidationResult validationResult,List rawMovements, String username, String exchangeLogGuid) throws RulesServiceException { try { // Enrich with MobilTerminal and Assets data. Get Mobile Terminal if it exists. EnrichedMovementWrapper enrichedWrapper = enrichBatchWithMobileTerminalAndAssets(rawMovements); CreateMovementBatchResponse movementBatchResponse = sendBatchToMovement(enrichedWrapper.getAssetList(), rawMovements, username); ExchangeLogStatusTypeType status; if (movementBatchResponse != null && 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()); + sendBatchBackToExchange(exchangeLogGuid, rawMovements, MovementRefTypeType.MOVEMENT, username); } else { status = ExchangeLogStatusTypeType.FAILED; } @@ -291,18 +339,18 @@ private void enrichAndSenMovementsAsBatch(EnrichedMovementWrapper enrichedWrappe } } - private EnrichedMovementWrapper processReceivedMovementsAsBatch(List rawMovements, String pluginType, String username, String exchangeLogGuid) throws RulesServiceException { + private void processReceivedMovementsAsBatch(List rawMovements, String pluginType, String username, String exchangeLogGuid) throws RulesServiceException { try { // Enrich with MobilTerminal and Assets data. Get Mobile Terminal if it exists. 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)) { @@ -318,7 +366,6 @@ private EnrichedMovementWrapper processReceivedMovementsAsBatch(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 false; } } - return areAllOk; + + return true; } private List getMobileTerminalByRawMovementsBatch(List rawMovements) throws MessageException, MobileTerminalModelMapperException, MobileTerminalUnmarshallException, JMSException { 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..4c4d8fab9 --- /dev/null +++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/fact/MovementReportDocumentFact.java @@ -0,0 +1,31 @@ +/* +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 eu.europa.ec.fisheries.schema.rules.template.v1.FactType; +import eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact; +import lombok.Data; + +import java.util.Date; + +@Data +public class MovementReportDocumentFact extends AbstractFact { + + private boolean ok = true; + private Date creationDateTime; + private String creationDateTimeString; + + @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/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..80d22f9d6 --- /dev/null +++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/business/generator/MovementFactGenerator.java @@ -0,0 +1,72 @@ +/* +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 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)); + } + + String df = (String) extraValueMap.get(DATA_FLOW); + facts.forEach(fact -> fact.setMessageDataFlow(df)); + 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..b8da4fea9 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,7 @@ 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"), 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/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/XPathConstants.java b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/constants/XPathConstants.java index e614b8c36..c7f972fb1 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"; 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..e42e8987b --- /dev/null +++ b/service/src/main/java/eu/europa/ec/fisheries/uvms/rules/service/mapper/fact/MovementReportDocumentFactMapper.java @@ -0,0 +1,102 @@ +/* +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 eu.europa.ec.fisheries.uvms.rules.service.business.AbstractFact; +import eu.europa.ec.fisheries.uvms.rules.service.business.fact.MovementReportDocumentFact; +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 un.unece.uncefact.data.standard.fluxvesselpositionmessage._4.FLUXVesselPositionMessage; +import un.unece.uncefact.data.standard.unqualifieddatatype._18.DateTimeType; + +import java.util.Date; + +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; + +@Slf4j +public class MovementReportDocumentFactMapper { + + private XPathStringWrapper xPathUtil; + + public MovementReportDocumentFactMapper() { + xPathUtil = new XPathStringWrapper(); + } + public MovementReportDocumentFactMapper(XPathStringWrapper strUtil1) { + this.xPathUtil = strUtil1; + } + + public AbstractFact generateFactForMovementReportDocument(FLUXVesselPositionMessage vesselPositionMessage){ + + if(vesselPositionMessage == null){ + 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); + + return fact; + } + + 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/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/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