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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions LIQUIBASE/changelog/db-changelog-master.xml
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,5 @@
<include file="changelog/v3.4/db-changelog-UNIONVMS-4477.xml" />
<include file="changelog/v3.4/db-changelog-UNIONVMS-4685.xml" />
<include file="changelog/v3.4/db-changelog-UNIONVMS-4660.xml" />
<include file="changelog/v3.4/db-changelog-UNIONVMS-4945.xml" />
</databaseChangeLog>
29 changes: 29 additions & 0 deletions LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4660.xml
Original file line number Diff line number Diff line change
Expand Up @@ -498,4 +498,33 @@
</rollback>
</changeSet>

<changeSet id="UNIONVMS-4660-update-VP-L03-00-0004" author="gmanifavas">
<insert tableName="rule">
<column name="template_id" value="2000" />
<column name="property_names" value="id" />
<column name="note" value="" />
<column name="level" value="L03" />
<column name="error_type" value="ERROR" />
<column name="disabled" value="false" />
<column name="br_id" value="VP-L03-00-0004" />
<column name="rule_id" value="20004"/>
</insert >
<insert tableName="context_expression">
<column name="expression" value="!isEmpty(existingIds) &amp;&amp; hasDuplicateId(ids, existingIds)"/>
<column name="failure_message" value="Message ID already exists."/>
<column name="context" value="EU"/>
<column name="rule_id" value="20004"/>
<column name="id" value="20004"/>
</insert >

<rollback>
<delete tableName="context_expression">
<where>rule_id = 20004</where>
</delete>
<delete tableName="rule">
<where>br_id = 'VP-L03-00-0004'</where>
</delete>
</rollback>
</changeSet>

</databaseChangeLog>
28 changes: 28 additions & 0 deletions LIQUIBASE/changelog/v3.4/db-changelog-UNIONVMS-4945.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd">

<changeSet id="UNIONVMS-4945-movement-id-tables" author="gmanifavas">
<createTable tableName="movement_doc_id_lock">
<column name="uuid" type="varchar(50)">
<constraints primaryKey="true" primaryKeyName="movement_doc_id_lock_pk"/>
</column>
</createTable>

<createTable tableName="movement_doc_id">
<column name="id" type="bigint">
<constraints nullable="false" primaryKey="true" primaryKeyName="movement_doc_id_pk"/>
</column>
<column name="uuid" type="TEXT">
<constraints nullable="false"/>
</column>
<column name="created_on" type="TIMESTAMP">
<constraints nullable="false"/>
</column>
</createTable>

<createIndex tableName="movement_doc_id" indexName="movement_doc_id_guid_inx">
<column name="uuid"/>
</createIndex>
</changeSet>
</databaseChangeLog>
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
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 <http://www.gnu.org/licenses/>.
*/

package eu.europa.ec.fisheries.uvms.rules.dao;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import eu.europa.ec.fisheries.uvms.commons.service.dao.AbstractDAO;
import eu.europa.ec.fisheries.uvms.rules.entity.MovementDocumentId;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;

public class MovementDocumentIdDao extends AbstractDAO<MovementDocumentId> {

private EntityManager em;

public MovementDocumentIdDao(EntityManager em) {
this.em = em;
}

@Override public EntityManager getEntityManager() {
return em;
}

public List<MovementDocumentId> loadMovementDocumentIDByIds(Set<MovementDocumentId> ids) {
Set<String> stringSet = new HashSet<>();
if(CollectionUtils.isEmpty(ids)){
return new ArrayList<>();
}
for (MovementDocumentId id : ids) {
String uuid = id.getUuid();
if(StringUtils.isNotEmpty(uuid)){
stringSet.add(uuid);
stringSet.add(uuid.toLowerCase());
stringSet.add(uuid.toUpperCase());
}
}
Query query = getEntityManager().createNamedQuery(MovementDocumentId.LOAD_BY_UUID);
query.setParameter("uuids", stringSet);
return query.getResultList();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package eu.europa.ec.fisheries.uvms.rules.dao;

import javax.ejb.Local;

@Local
public interface MovementDocumentIdLockDao {
void takeNoteOfDocumentIdInNewTx(String documentId);

void lock(String documentId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.entity.AlarmReport;
import eu.europa.ec.fisheries.uvms.rules.entity.CustomRule;
import eu.europa.ec.fisheries.uvms.rules.entity.FADocumentID;
import eu.europa.ec.fisheries.uvms.rules.entity.MovementDocumentId;
import eu.europa.ec.fisheries.uvms.rules.entity.PreviousReport;
import eu.europa.ec.fisheries.uvms.rules.entity.RawMessage;
import eu.europa.ec.fisheries.uvms.rules.entity.RuleSubscription;
Expand Down Expand Up @@ -168,13 +169,21 @@ List<Ticket> getTicketListPaginated(Integer page, Integer listSize, String sql,
List<ValidationMessage> getValidationMessagesByRawMsgGuid(String rawMsgGuid, String type) throws DaoException;

List<FADocumentID> loadFADocumentIDByIdsByIds(Set<FADocumentID> incomingIDs);

List<MovementDocumentId> loadMovementDocumentIDByIds(Set<MovementDocumentId> incomingIDs);

void takeNoteOfDocumentIds(Set<FADocumentID> incomingIDs);

void takeNoteOfMovementDocumentIds(Set<MovementDocumentId> incomingIDs);

List<String> lockDocumentIds(Set<FADocumentID> incomingIDs);

List<String> lockMovementDocumentIds(Set<MovementDocumentId> incomingIDs);

void createFaDocumentIdEntity(Set<FADocumentID> incomingID) throws ServiceException;


void createMovementDocumentIdEntity(Set<MovementDocumentId> incomingID) throws ServiceException;

void saveFaIdsPerTripList(List<String> tripList);

List<String> loadExistingFaIdsPerTrip(List<String> idsFromIncommingMessage);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package eu.europa.ec.fisheries.uvms.rules.dao.bean;

import static javax.ejb.TransactionAttributeType.REQUIRES_NEW;

import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.persistence.EntityManager;
import javax.persistence.LockModeType;
import javax.persistence.PersistenceContext;
import java.util.Collections;
import java.util.Map;

import eu.europa.ec.fisheries.uvms.rules.dao.MovementDocumentIdLockDao;
import eu.europa.ec.fisheries.uvms.rules.entity.MovementDocumentIdLock;

@Stateless
public class MovementDocumentIdLockDaoBean implements MovementDocumentIdLockDao {

private static final Map<String,Object> ZERO_LOCK_TIMEOUT = Collections.singletonMap("javax.persistence.lock.timeout", 0);

@PersistenceContext(unitName = "rulesPostgresPU")
public EntityManager em;

@TransactionAttribute(REQUIRES_NEW)
@Override
public void takeNoteOfDocumentIdInNewTx(String documentId) {
MovementDocumentIdLock lock = em.find(MovementDocumentIdLock.class, documentId);
if( lock == null ) {
em.persist(new MovementDocumentIdLock(documentId));
}
}

@Override
public void lock(String documentId) {
MovementDocumentIdLock lock = em.find(MovementDocumentIdLock.class, documentId, LockModeType.PESSIMISTIC_WRITE, ZERO_LOCK_TIMEOUT);
if( lock == null ) {
throw new IllegalStateException("lock " + documentId + " should have been created");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.dao.FADocumentIDDAO;
import eu.europa.ec.fisheries.uvms.rules.dao.FaDocumentIdLockDao;
import eu.europa.ec.fisheries.uvms.rules.dao.FaIdsPerTripDao;
import eu.europa.ec.fisheries.uvms.rules.dao.MovementDocumentIdDao;
import eu.europa.ec.fisheries.uvms.rules.dao.MovementDocumentIdLockDao;
import eu.europa.ec.fisheries.uvms.rules.dao.RawMessageDao;
import eu.europa.ec.fisheries.uvms.rules.dao.RulesDao;
import eu.europa.ec.fisheries.uvms.rules.dao.TemplateDao;
Expand All @@ -41,6 +43,7 @@ This file is part of the Integrated Fisheries Data Management (IFDM) Suite. The
import eu.europa.ec.fisheries.uvms.rules.entity.CustomRule;
import eu.europa.ec.fisheries.uvms.rules.entity.FADocumentID;
import eu.europa.ec.fisheries.uvms.rules.entity.FaIdsPerTrip;
import eu.europa.ec.fisheries.uvms.rules.entity.MovementDocumentId;
import eu.europa.ec.fisheries.uvms.rules.entity.PreviousReport;
import eu.europa.ec.fisheries.uvms.rules.entity.RawMessage;
import eu.europa.ec.fisheries.uvms.rules.entity.RuleSubscription;
Expand All @@ -67,10 +70,14 @@ public class RulesDaoBean implements RulesDao {
private ValidationMessageDao validationMessageDao;
private FADocumentIDDAO fishingActivityIdDao;
private FaIdsPerTripDao faIdsPerTripDao;
private MovementDocumentIdDao movementDocumentIdDao;

@EJB
private FaDocumentIdLockDao faDocumentIdLockDao;

@EJB
private MovementDocumentIdLockDao movementDocumentIdLockDao;

@PersistenceContext(unitName = "rulesPostgresPU")
public EntityManager em;

Expand All @@ -81,6 +88,7 @@ public void init() {
validationMessageDao = new ValidationMessageDao(em);
fishingActivityIdDao = new FADocumentIDDAO(em);
faIdsPerTripDao = new FaIdsPerTripDao(em);
movementDocumentIdDao = new MovementDocumentIdDao(em);
}

@Override
Expand Down Expand Up @@ -617,6 +625,11 @@ public List<FADocumentID> loadFADocumentIDByIdsByIds(Set<FADocumentID> incomingI
return fishingActivityIdDao.loadFADocumentIDByIdsByIds(incomingIDs);
}

@Override
public List<MovementDocumentId> loadMovementDocumentIDByIds(Set<MovementDocumentId> incomingIDs) {
return movementDocumentIdDao.loadMovementDocumentIDByIds(incomingIDs);
}

@Override
public void takeNoteOfDocumentIds(Set<FADocumentID> incomingIDs) {
incomingIDs.stream()
Expand All @@ -625,6 +638,14 @@ public void takeNoteOfDocumentIds(Set<FADocumentID> incomingIDs) {
.forEach(this::takeNoteOfDocumentIdAllowingDuplicates);
}

@Override
public void takeNoteOfMovementDocumentIds(Set<MovementDocumentId> incomingIDs) {
incomingIDs.stream()
.map(MovementDocumentId::getUuid)
.sorted()
.forEach(this::takeNoteOfMovementDocumentIdAllowingDuplicates);
}

private void takeNoteOfDocumentIdAllowingDuplicates(String documentId) {
try {
faDocumentIdLockDao.takeNoteOfDocumentIdInNewTx(documentId);
Expand All @@ -633,6 +654,14 @@ private void takeNoteOfDocumentIdAllowingDuplicates(String documentId) {
}
}

private void takeNoteOfMovementDocumentIdAllowingDuplicates(String documentId) {
try {
movementDocumentIdLockDao.takeNoteOfDocumentIdInNewTx(documentId);
} catch( EntityExistsException eee ) {
// ignore it
}
}

public List<String> lockDocumentIds(Set<FADocumentID> incomingIDs) {
return incomingIDs.stream()
.map(FADocumentID::getUuid)
Expand All @@ -641,6 +670,15 @@ public List<String> lockDocumentIds(Set<FADocumentID> incomingIDs) {
.collect(Collectors.toList());
}

@Override
public List<String> lockMovementDocumentIds(Set<MovementDocumentId> incomingIDs) {
return incomingIDs.stream()
.map(MovementDocumentId::getUuid)
.sorted()
.peek(movementDocumentIdLockDao::lock)
.collect(Collectors.toList());
}

@Override
public void createFaDocumentIdEntity(Set<FADocumentID> incomingIDsList) throws ServiceException {
if(CollectionUtils.isNotEmpty(incomingIDsList)){
Expand All @@ -650,6 +688,13 @@ public void createFaDocumentIdEntity(Set<FADocumentID> incomingIDsList) throws S
}
}

@Override
public void createMovementDocumentIdEntity(Set<MovementDocumentId> incomingID) throws ServiceException {
for(MovementDocumentId movementDocumentId: incomingID) {
movementDocumentIdDao.createEntity(movementDocumentId);
}
}

@Override
public void saveFaIdsPerTripList(List<String> tripList) {
if(CollectionUtils.isNotEmpty(tripList)){
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
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 <http://www.gnu.org/licenses/>.
*/

package eu.europa.ec.fisheries.uvms.rules.entity;

import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.PrePersist;
import javax.persistence.Table;
import java.io.Serializable;

import eu.europa.ec.fisheries.uvms.commons.date.DateUtils;
import eu.europa.ec.fisheries.uvms.commons.domain.Audit;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;

@Table(name = "movement_doc_id")
@Data
@Entity
@EqualsAndHashCode(exclude = {"id", "audit"})
@NamedQueries({
@NamedQuery(name = MovementDocumentId.LOAD_BY_UUID, query = "FROM MovementDocumentId f WHERE f.uuid in (:uuids)")
})
@RequiredArgsConstructor
@NoArgsConstructor
public class MovementDocumentId implements Serializable {

public static final String LOAD_BY_UUID = "MovementDocumentId.loadByUUID";

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@NonNull
private String uuid;

@Embedded
private Audit audit = new Audit();

@PrePersist
private void prePersist() {
audit.setCreatedOn(DateUtils.nowUTC().toDate());
}

}
Loading