EventRepositoryImpl.java
package com.tradecloud.repository.impl;
import com.tradecloud.authentication.MultiTenantUtil;
import com.tradecloud.authentication.User;
import com.tradecloud.domain.model.accounting.Snapshot;
import com.tradecloud.domain.model.events.*;
import com.tradecloud.domain.model.organisationalunit.OrganisationalUnit;
import com.tradecloud.dto.event.EventDTO;
import com.tradecloud.dto.event.EventsSearch;
import com.tradecloud.repository.EventRepository;
import com.tradecloud.repository.SearchMetaParams;
import com.tradecloud.repository.base.impl.RepositoryBaseImpl;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.*;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Event Repository.
*/
@Repository(value = "eventRepository")
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
public class EventRepositoryImpl extends RepositoryBaseImpl<Event, EventsSearch> implements EventRepository {
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger(EventRepositoryImpl.class);
private final int DUPLICATE_EVENT_WITHIN_SECONDS = 20; // 20 seconds
@Override
public void storeEvent(Event event) {
saveOrUpdate(event);
}
@Override
public void removeEvents(List<Long> eventIds) {
List<Event> events = new ArrayList<Event>();
for (Long eventId : eventIds) {
events.add((Event) getCurrentSession().load(Event.class, eventId));
}
deleteAll(events);
}
@Override
public List<OrderEvent> getOrderEvents() {
return getAllEvents("findAllOrderEventsForUser");
}
@Override
public List<CostingEvent> getCostingEvents() {
return getAllEvents("findAllCostingEventsForUser");
}
/**
* {@inheritDoc}
*/
@Override
public List<LogisticsEvent> getLogisticsEvents() {
return getAllEvents("findAllLogisticEventsForUser");
}
@Override
public List<CostingEvent> getCostingEvents(List<Long> eventIds) {
return getEvents(eventIds, CostingEvent.class);
}
@Override
public List<Event> getEvents(List<Long> eventIds) {
return getEvents(eventIds, Event.class);
}
@Override
public List<ProductEvent> getProductEvents() {
return getAllEvents("findAllProductEventsForUser");
}
@Override
public List<SuppliersEvent> getSupplierEvents() {
return getAllEvents("findAllSupplierEventsForUser");
}
@Override
public List<AccountingEvent> getAccountingEvents() {
return getAllEvents("findAllAccountingEventsForUser");
}
@Override
public List<AccountingEvent> getAccountingEvents(List<Long> eventIds) {
return getEvents(eventIds, AccountingEvent.class);
}
@Override
public Event getEvent(AccountingEvent.AccountingEventType accountingEventType, String reference) {
return getEventByTypeAndReference("findEventByTypeAndReference", accountingEventType, reference);
}
@Override
public List<DealEvent> getDealEvents() {
String namedQuery = "findAllDealEventForUser";
return getAllEvents(namedQuery);
}
private <T extends Event> List<T> getAllEvents(String namedQuery) {
User user = MultiTenantUtil.getActiveUser();
List<T> results =
(List<T>) findByNamedQueryAndNamedParam(namedQuery, "consumerTag", user.getUsername());
return results;
}
private Event getEventByTypeAndReference(String namedQuery,
AccountingEvent.AccountingEventType accountingEventType,
String reference) {
List<Event> results =
(List<Event>) getNamedQueryAndNamedParam(namedQuery,
new String[]{"eventType", "reference"}, new Object[]{accountingEventType.name(), reference});
return results.isEmpty() ? null : results.get(0);
}
public List<DealEvent> getDealEvents(List<Long> eventIds) {
return getEvents(eventIds, DealEvent.class);
}
private <T extends Event> List<T> getEvents(List<Long> eventIds, Class<T> aClass) {
@SuppressWarnings("unchecked")
List<T> dealEvents = getSessionCustom().createQuery("from " + aClass.getSimpleName() + " where id in (:eventIds)")
.setParameterList("eventIds", eventIds).list();
return dealEvents;
}
@Override
public <T extends Event> long countByReferences(Set<String> referencesSet, Class<T> aClass) {
long uniqueResult = (long) getSessionCustom().createQuery("select count(distinct e.reference) from " + aClass.getSimpleName() +
" e where reference in (:referencesSet)")
.setParameterList("referencesSet", new ArrayList(referencesSet)).uniqueResult();
return uniqueResult;
}
// @Override
// public List<? extends Event> searchEvents(EventsSearch eventsSearch) {
// DetachedCriteria searchCriteria = DetachedCriteria.forClass(eventsSearch.getEventClass());
// if (StringUtils.isNotEmpty(eventsSearch.getEventType())) {
// searchCriteria.add(Restrictions.eq("eventType", eventsSearch.getEventType()));
// }
// if (eventsSearch.getReferences() != null && !eventsSearch.getReferences().isEmpty()) {
// searchCriteria.add(Restrictions.in("reference", eventsSearch.getReferences()));
// }
// if (eventsSearch.getOrganisationalunit() != null && !eventsSearch.getOrganisationalunit().isEmpty()) {
// searchCriteria.add(Restrictions.in("organisationalUnit", eventsSearch.getOrganisationalunit()));
// }
// if (eventsSearch.getConsumerTag() != null && !eventsSearch.getConsumerTag().isEmpty()) {
// searchCriteria.add(Restrictions.in("consumerTag", eventsSearch.getConsumerTag()));
// }
// return getExecutableCriteriaList(searchCriteria,eventsSearch.getSearchMetaParams());
//
// }
@Override
public List<Event> search(EventsSearch eventsSearch) {
CriteriaBuilder builder = getSessionCustom().getCriteriaBuilder();
CriteriaQuery criteria = builder.createQuery(eventsSearch.getEventClass());
Root root = criteria.from(eventsSearch.getEventClass());
criteria.select(root);
buidPredicates(eventsSearch, builder, criteria, root);
SearchMetaParams metaParams = eventsSearch.getSearchMetaParams();
criteria.orderBy(builder.desc(root.get("timestamp")));
Query query = getSessionCustom().createQuery(criteria);
if (metaParams != null && metaParams.isPaged()) {
query.setFirstResult(metaParams.getRowIndex());
query.setMaxResults(metaParams.getRowCount());
}
List resultList = query.getResultList();
return resultList;
}
@Override
public long count(EventsSearch eventsSearch) {
CriteriaBuilder builder = getSessionCustom().getCriteriaBuilder();
CriteriaQuery criteria = builder.createQuery(Long.class);
Root root = criteria.from(eventsSearch.getEventClass());
criteria.select(builder.count(root));
buidPredicates(eventsSearch, builder, criteria, root);
Query<Long> query = getSessionCustom().createQuery(criteria);
return query.uniqueResult();
}
private void buidPredicates(EventsSearch eventsSearch, CriteriaBuilder builder, CriteriaQuery criteria, Root root) {
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotEmpty(eventsSearch.getEventType())) {
predicates.add(builder.equal(root.get("eventType"), eventsSearch.getEventType()));
}
if (eventsSearch.getReferences() != null && !eventsSearch.getReferences().isEmpty()) {
predicates.add(root.get("reference").in(eventsSearch.getReferences()));
} else if (eventsSearch.getReference() != null && !eventsSearch.getReference().isEmpty()) {
predicates.add(builder.like(builder.lower(root.get("reference")), "%" + eventsSearch.getReference().toLowerCase() + "%"));
}
if (eventsSearch.getOrganisationalunit() != null && !eventsSearch.getOrganisationalunit().isEmpty()) {
predicates.add(root.get("organisationalUnit").in(eventsSearch.getOrganisationalunit()));
}
if (eventsSearch.getOrganisationalUnit() != null) {
predicates.add(builder.equal(root.get("organisationalUnitId"), eventsSearch.getOrganisationalUnit().getId()));
} else if (eventsSearch.getOrganisationalUnits() != null && !eventsSearch.getOrganisationalUnits().isEmpty()) {
List<Long> collect = (List<Long>) eventsSearch.getOrganisationalUnits().stream()
.map(o -> ((OrganisationalUnit) o).getId()).collect(Collectors.toList());
predicates.add(root.get("organisationalUnitId")
.in(collect));
}
if (eventsSearch.getConsumerTag() != null && !eventsSearch.getConsumerTag().isEmpty()) {
predicates.add(builder.equal(root.get("consumerTag"), eventsSearch.getConsumerTag()));
}
if (eventsSearch.getReinstateUser() != null && !eventsSearch.getReinstateUser().isEmpty()) {
predicates.add(builder.like(builder.lower(root.get("reinstateUser")), "%" + eventsSearch.getReinstateUser().toLowerCase() + "%"));
}
if (eventsSearch.getFrom() != null) {
predicates.add(builder.greaterThanOrEqualTo(root.get("timestamp"), eventsSearch.getFrom()));
}
if (eventsSearch.getTo() != null) {
predicates.add(builder.lessThanOrEqualTo(root.get("timestamp"), eventsSearch.getTo()));
}
if (eventsSearch.getStates() != null && !eventsSearch.getStates().isEmpty()) {
predicates.add(root.get("state").in(eventsSearch.getStates()));
} else if (StringUtils.isNotEmpty(eventsSearch.getState())) {
predicates.add(builder.equal(root.get("state"), eventsSearch.getState()));
}
if (eventsSearch.getEventId() != null ) {
predicates.add(builder.like(root.get("id").as(String.class), "%" + eventsSearch.getEventId()+ "%"));
}
if (eventsSearch.getPaymentId() != null ) {
predicates.add(builder.equal(root.get("paymentId"), eventsSearch.getPaymentId()));
}
if (!predicates.isEmpty()) {
Predicate[] toArray = predicates.stream().toArray(Predicate[]::new);
criteria.where(toArray);
}
}
@Override
public void deleteDealExposure(String shipmentRef, String invoiceRef) {
CriteriaBuilder builder = getSessionCustom().getCriteriaBuilder();
CriteriaDelete criteriaDelete = builder.createCriteriaDelete(DealExposureEvent.class);
final Root root = criteriaDelete.from(DealExposureEvent.class);
criteriaDelete.where(builder.equal(root.get("shipmentReference"), shipmentRef),
builder.equal(root.get("invoiceReference"), invoiceRef));
Query query = getSessionCustom().createQuery(criteriaDelete);
query.executeUpdate();
}
@Override
public String findInvoiceExposureEventFailMessage(Long invoiceId) {
return (String) getCurrentSession()
.createNativeQuery("select e.notes from invoiceexposureevent c join event e on (e.id=c.id) " +
"where invoiceid=:invoiceId and state='Failed' order by e.timestamp desc limit 1;")
.setParameter("invoiceId", invoiceId).uniqueResult();
}
@Override
public String findDealExposureEventFailMessage(String invoiceRef, String shipRef) {
return (String) getCurrentSession()
.createNativeQuery("select e.notes from dealexposureevent c join event e on (e.id=c.id) " +
"where c.invoicereference=:invoicereference and c.shipmentreference=:shipmentreference " +
" and state='Failed' order by e.timestamp desc limit 1;")
.setParameter("invoicereference", invoiceRef).setParameter("shipmentreference", shipRef).uniqueResult();
}
@Override
public List<String> findInvoiceExposureEventNotProcessed(Set<String> invoices, String shipmentRef) {
return getCurrentSession()
.createNativeQuery("select ci.reference from invoiceexposureevent e join event v on (v.id=e.id) " +
" join costsinvoice ci on (ci.id=e.invoiceid) where v.state not in ('Consumed','Failed') " +
"and shipmentreference=:shipmentreference and ci.reference in (:invoices);")
.setParameter("invoices", invoices).setParameter("shipmentreference", shipmentRef).list();
}
@Override
public List<EventDTO> searchDTO(EventsSearch search) {
CriteriaBuilder builder = getSessionCustom().getCriteriaBuilder();
CriteriaQuery<EventDTO> criteria = builder.createQuery(search.getEventClass());
Root root = criteria.from(search.getEventClass());
Join<Event, Snapshot> snapshotJoin = root.join("snapshot", JoinType.LEFT);
criteria.select(builder.construct(EventDTO.class, root.get("id"), root.get("timestamp"), root.get("reference"),
root.get("organisationalUnit"), root.get("eventType"), root.get("state"), root.get("consumerTag"), root.get("reinstateUser"),
root.get("consumedDate"), snapshotJoin.get("acknowledgeEventId"), root.get("notes")));
//Expression<Class> localExp = builder.literal(root.getJavaType());
//localExp.alias("instanceClass");
buidPredicates(search, builder, criteria, root);
SearchMetaParams metaParams = search.getSearchMetaParams();
criteria.orderBy(builder.desc(root.get("timestamp")));
//Query query = getSessionCustom().createQuery(criteria);
TypedQuery<EventDTO> query = getSessionCustom().createQuery(criteria);
if (metaParams != null && metaParams.isPaged()) {
query.setFirstResult(metaParams.getRowIndex());
query.setMaxResults(metaParams.getRowCount());
}
List resultList = query.getResultList();
return resultList;
}
@Override
public Long findLastEventId(String tableName, String reference, String evenType) {
BigInteger bigInteger = (BigInteger) getCurrentSession()
.createNativeQuery("select e.id from " + tableName + " e join event v on (v.id=e.id) " +
" where v.eventType =:evenType" +
" and v.reference=:reference order by v.created desc limit 1;")
.setParameter("evenType", evenType).setParameter("reference", reference).uniqueResult();
return bigInteger!=null?bigInteger.longValue():null;
}
}