Java tutorial
/******************************************************************************* * Copyright (c) 2013 - 2016 QPark Consulting S.a r.l. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0. * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html. ******************************************************************************/ package com.qpark.eip.core.spring.statistics.dao; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import java.util.List; import java.util.TimeZone; import javax.persistence.EntityManager; import javax.persistence.NoResultException; import javax.persistence.NonUniqueResultException; import javax.persistence.PersistenceContext; import javax.persistence.TypedQuery; import javax.persistence.criteria.CriteriaBuilder; import javax.persistence.criteria.CriteriaDelete; import javax.persistence.criteria.CriteriaQuery; import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Root; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.qpark.eip.core.domain.persistencedefinition.ApplicationUserLogType; import com.qpark.eip.core.domain.persistencedefinition.ApplicationUserLogType_; import com.qpark.eip.core.domain.persistencedefinition.FlowLogMessageType; import com.qpark.eip.core.domain.persistencedefinition.FlowLogMessageType_; import com.qpark.eip.core.domain.persistencedefinition.SystemUserLogType; import com.qpark.eip.core.domain.persistencedefinition.SystemUserLogType_; import com.qpark.eip.core.persistence.AbstractEipDao; import com.qpark.eip.core.persistence.config.EipPersistenceConfig; import com.qpark.eip.core.spring.ContextNameProvider; import com.qpark.eip.core.spring.statistics.config.EipStatisticsConfig; /** * DAO to access the authority database and to log the user calls. * * @author bhausen */ public class StatisticsLoggingDao extends AbstractEipDao { private static final TimeZone LOGGING_TIMEZONE = TimeZone.getTimeZone("UTC"); /** * Get a {@link Date}, where hours, minutes, seconds and milliseconds are * set to 0. * * @return the {@link Date} . */ private static Date getDayEnd(final Date d) { final Calendar gc = new GregorianCalendar(LOGGING_TIMEZONE); gc.setTime(d); gc.set(Calendar.HOUR_OF_DAY, 23); gc.set(Calendar.MINUTE, 59); gc.set(Calendar.SECOND, 59); gc.set(Calendar.MILLISECOND, 0); return gc.getTime(); } /** * Get a {@link Date}, where hours, minutes, seconds and milliseconds are * set to 0. * * @return the {@link Date} . */ private static Date getDayStart(final Date d) { final Calendar gc = new GregorianCalendar(LOGGING_TIMEZONE); gc.setTime(d); gc.set(Calendar.HOUR_OF_DAY, 0); gc.set(Calendar.MINUTE, 0); gc.set(Calendar.SECOND, 0); gc.set(Calendar.MILLISECOND, 0); return gc.getTime(); } /** The eip {@link ContextNameProvider}. */ @Autowired @Qualifier(EipStatisticsConfig.CONTEXTNAME_PROVIDER_BEAN_NAME) private ContextNameProvider contextNameProvider; /** The {@link EntityManager}. */ @PersistenceContext(unitName = EipPersistenceConfig.PERSISTENCE_UNIT_NAME, name = EipPersistenceConfig.ENTITY_MANAGER_FACTORY_NAME) private EntityManager em; /** The {@link org.slf4j.Logger}. */ private final Logger logger = LoggerFactory.getLogger(StatisticsLoggingDao.class); /** * Add the {@link ApplicationUserLogType} to the database. * * @param log * the {@link ApplicationUserLogType} to add. */ private void addChannelInvocation(final ApplicationUserLogType log) { if (this.logger.isTraceEnabled()) { this.logger.trace("{},{},{},{},{},{},{},{}", log.getContext(), log.getHostName(), log.getServiceName(), log.getOperationName(), log.getUserName(), log.getReturnedFailures(), log.getDurationString(), log.getStartItem()); } this.em.persist(log); } /** * Add the {@link SystemUserLogType} to the database. * * @param log * the {@link SystemUserLogType} to add. */ private void addChannelInvocation(final SystemUserLogType log) { /* Setup context and version. */ log.setContext(this.getContextName()); log.setVersion(this.getContextVersion()); if (log.getUserName() != null && log.getUserName().trim().length() == 0) { log.setUserName(null); } /* Setup to search existing one. */ final CriteriaBuilder cb = this.em.getCriteriaBuilder(); final CriteriaQuery<SystemUserLogType> q = cb.createQuery(SystemUserLogType.class); final Root<SystemUserLogType> c = q.from(SystemUserLogType.class); final List<Predicate> predicates = new ArrayList<Predicate>(); predicates.add(cb.equal(c.<String>get(SystemUserLogType_.context), log.getContext())); predicates.add(cb.equal(c.<String>get(SystemUserLogType_.version), log.getVersion())); if (log.getUserName() == null) { predicates.add(cb.isNull(c.<String>get(SystemUserLogType_.userName))); } else { predicates.add(cb.equal(c.<String>get(SystemUserLogType_.userName), log.getUserName())); } predicates.add(cb.equal(c.<String>get(SystemUserLogType_.serviceName), log.getServiceName())); predicates.add(cb.equal(c.<String>get(SystemUserLogType_.operationName), log.getOperationName())); predicates.add(cb.between(c.<Date>get(SystemUserLogType_.logDateItem), getDayStart(log.getLogDateItem()), getDayEnd(log.getLogDateItem()))); q.where(predicates.toArray(new Predicate[predicates.size()])); q.orderBy(cb.desc(c.<Long>get(SystemUserLogType_.hjid))); TypedQuery<SystemUserLogType> typedQuery = this.em.createQuery(q); SystemUserLogType persistence = null; synchronized (StatisticsLoggingDao.class) { try { persistence = typedQuery.getSingleResult(); if (persistence == null) { /* Not found -> persist */ persistence = log; this.setupSystemUserLog(persistence, null); this.em.persist(persistence); } else { /* Found -> add and merge */ this.setupSystemUserLog(persistence, log); this.em.merge(persistence); } } catch (final NoResultException e) { /* Not found -> persist */ persistence = log; this.setupSystemUserLog(persistence, null); this.em.persist(persistence); } catch (final NonUniqueResultException e) { /* Found more */ typedQuery = this.em.createQuery(q); final List<SystemUserLogType> list = typedQuery.getResultList(); SystemUserLogType l; for (int i = 0; i < list.size(); i++) { l = list.get(i); if (persistence == null && l.getHjid() != null) { persistence = l; break; } } if (persistence != null) { /* Found more -> condense to first valid one -> merge. */ this.setupSystemUserLog(persistence, log); for (int i = list.size() - 1; i >= 0; i--) { l = list.get(i); if (l != null && l.getHjid() != null) { if (persistence.getHjid().equals(l.getHjid())) { } else { this.setupSystemUserLog(persistence, l); list.remove(i); this.em.remove(l); } } } this.em.merge(persistence); } else { /* Found more -> no valid one in list -> persist. */ persistence = log; this.setupSystemUserLog(persistence, null); this.em.persist(persistence); } } } this.logger.debug("addChannelInvocation SystemUserLog {} {} {} {} {} {}", this.contextNameProvider.getContextName(), this.contextNameProvider.getContextVersion(), String.valueOf(persistence.getUserName()), persistence.getServiceName(), persistence.getOperationName(), persistence.getLogDate().toXMLFormat()); } /** * Add the {@link FlowLogMessageType} to the database. * * @param log * the {@link FlowLogMessageType} to add. */ private void addFlowLogMessage(final FlowLogMessageType log) { this.em.persist(log); } /** * @see com.qpark.eip.core.persistence.BusUtilDao#doAsyncDatabaseOperation(java.lang.String, * java.lang.Object) */ @Override @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public void doAsyncDatabaseOperation(final String userName, final Object obj) { if (ApplicationUserLogType.class.isInstance(obj)) { this.addChannelInvocation((ApplicationUserLogType) obj); } else if (SystemUserLogType.class.isInstance(obj)) { this.addChannelInvocation((SystemUserLogType) obj); } else if (FlowLogMessageType.class.isInstance(obj)) { this.addFlowLogMessage((FlowLogMessageType) obj); } } /** * Erase all {@link ApplicationUserLogType}s of the application scope older * than the given date. * * @param toDate * the date. */ @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public void eraseApplicationUserLog(final Date toDate) { final CriteriaBuilder cb = this.em.getCriteriaBuilder(); final CriteriaDelete<ApplicationUserLogType> q = cb.createCriteriaDelete(ApplicationUserLogType.class); final Root<ApplicationUserLogType> c = q.from(ApplicationUserLogType.class); q.where(cb.lessThan(c.<Date>get(ApplicationUserLogType_.stopItem), toDate), cb .equal(c.<String>get(ApplicationUserLogType_.context), this.contextNameProvider.getContextName())); try { this.em.createQuery(q).executeUpdate(); } catch (final Exception e) { this.logger.error("eraseApplicationUserLog: {}", e.getMessage()); } } /** * Erase all {@link FlowLogMessageType}s of the application scope older than * the given date. * * @param toDate * the date. */ @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public void eraseFlowLogMessage(final Date toDate) { final CriteriaBuilder cb = this.em.getCriteriaBuilder(); final CriteriaDelete<FlowLogMessageType> q = cb.createCriteriaDelete(FlowLogMessageType.class); final Root<FlowLogMessageType> c = q.from(FlowLogMessageType.class); q.where(cb.lessThan(c.<Date>get(FlowLogMessageType_.logTimeItem), toDate)); try { this.em.createQuery(q).executeUpdate(); } catch (final Exception e) { this.logger.error("eraseFlowLogMessage: {}", e.getMessage()); } } /** * Erase all {@link SystemUserLogType}s of the application scope older than * the given date. * * @param toDate * the date. */ @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public void eraseSystemUserLog(final Date toDate) { final CriteriaBuilder cb = this.em.getCriteriaBuilder(); final CriteriaDelete<SystemUserLogType> q = cb.createCriteriaDelete(SystemUserLogType.class); final Root<SystemUserLogType> c = q.from(SystemUserLogType.class); q.where(cb.lessThan(c.<Date>get(SystemUserLogType_.logDateItem), toDate), cb.equal(c.<String>get(SystemUserLogType_.context), this.contextNameProvider.getContextName())); try { this.em.createQuery(q).executeUpdate(); } catch (final Exception e) { this.logger.error("eraseSystemUserLog: {}", e.getMessage()); } } /** * Get all {@link ApplicationUserLogType}s of the day of the application. * * @param date * the date the calls are recorded. * @return the list of {@link SystemUserLogType}s. */ @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public List<ApplicationUserLogType> getApplicationUserLogType(final Date date) { final CriteriaBuilder cb = this.em.getCriteriaBuilder(); Date d = date; if (d == null) { d = new Date(); } final CriteriaQuery<ApplicationUserLogType> q = cb.createQuery(ApplicationUserLogType.class); final Root<ApplicationUserLogType> c = q.from(ApplicationUserLogType.class); q.where(cb.equal(c.<String>get(ApplicationUserLogType_.context), this.contextNameProvider.getContextName()), cb.between(c.<Date>get(ApplicationUserLogType_.startItem), getDayStart(d), getDayEnd(d))); final TypedQuery<ApplicationUserLogType> typedQuery = this.em.createQuery(q); return typedQuery.getResultList(); } /** * @see com.qpark.eip.core.persistence.BusUtilDao#getContextName() */ @Override protected String getContextName() { return this.contextNameProvider.getContextName(); } /** * @see com.qpark.eip.core.persistence.BusUtilDao#getContextVersion() */ @Override protected String getContextVersion() { return this.contextNameProvider.getContextVersion(); } /** * @see com.qpark.eip.core.persistence.BusUtilDao#getEntityManager() */ @Override protected EntityManager getEntityManager() { return this.em; } /** * Get all {@link SystemUserLogType}s of the day of the application. * * @param date * the date the calls are recorded. * @return the list of {@link SystemUserLogType}s. */ @Transactional(value = EipPersistenceConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED) public List<SystemUserLogType> getSystemUserLogType(final Date date) { final CriteriaBuilder cb = this.em.getCriteriaBuilder(); Date d = date; if (d == null) { d = new Date(); } final CriteriaQuery<SystemUserLogType> q = cb.createQuery(SystemUserLogType.class); final Root<SystemUserLogType> c = q.from(SystemUserLogType.class); q.where(cb.equal(c.<String>get(SystemUserLogType_.context), this.contextNameProvider.getContextName()), cb.between(c.<Date>get(SystemUserLogType_.logDateItem), getDayStart(d), getDayEnd(d))); final TypedQuery<SystemUserLogType> typedQuery = this.em.createQuery(q); return typedQuery.getResultList(); } private void setupSystemUserLog(final SystemUserLogType l, final SystemUserLogType addition) { if (l != null && addition != null) { l.setRequestsDenied(l.getRequestsDenied() + addition.getRequestsDenied()); l.setRequestsGranted(l.getRequestsGranted() + addition.getRequestsGranted()); l.setResponseFaults(l.getResponseFaults() + addition.getResponseFaults()); } if (l != null && l.getRequestsGranted() == 0) { l.setRequestsGranted(1); } } }