com.qpark.eip.core.spring.lockedoperation.dao.LockedOperationDaoImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.qpark.eip.core.spring.lockedoperation.dao.LockedOperationDaoImpl.java

Source

/*******************************************************************************
 * Copyright (c) 2013 - 2017 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.lockedoperation.dao;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Date;
import java.util.List;

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.CriteriaQuery;
import javax.persistence.criteria.Root;

import org.slf4j.Logger;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.qpark.eip.core.DateUtil;
import com.qpark.eip.core.spring.lockedoperation.LockableOperation;
import com.qpark.eip.core.spring.lockedoperation.config.EipLockedoperationConfig;
import com.qpark.eip.core.spring.lockedoperation.model.OperationLockControllType;

/**
 * Implementation of the {@link LockableOperationDao}.
 *
 * @author bhausen
 */
public class LockedOperationDaoImpl implements LockableOperationDao {
    /**
     * @param operation
     * @return a unique lock string.
     */
    public static String getOperationLockString(final LockableOperation operation) {
        return new StringBuffer(operation.getUUID()).append("#").append(operation.getName()).toString();
    }

    /** The {@link EntityManager}. */
    @PersistenceContext(unitName = EipLockedoperationConfig.PERSISTENCE_UNIT_NAME, name = EipLockedoperationConfig.ENTITY_MANAGER_FACTORY_NAME)
    private EntityManager em;
    /** First run indicator. */
    private boolean firstRun = true;
    /** The IP address of the host. */
    private String hostAddress;
    /** The host name. */
    private String hostName;
    /** The {@link Logger}. */
    private final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LockedOperationDaoImpl.class);

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#getHostAddress()
     */
    @Override
    public String getHostAddress() {
        return this.hostAddress;
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#getHostName()
     */
    @Override
    public String getHostName() {
        return this.hostName;
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#isLockedByThisServer(com.qpark.eip.core.spring.lockedoperation.LockableOperation)
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public synchronized boolean isLockedByThisServer(final LockableOperation operation) {
        boolean lockedByThisServer = false;
        OperationLockControllType value = null;
        String logString = getOperationLockString(operation);
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<OperationLockControllType> q = cb.createQuery(OperationLockControllType.class);
        Root<OperationLockControllType> c = q.from(OperationLockControllType.class);
        q.where(cb.equal(c.<String>get("operationName"), logString));
        TypedQuery<OperationLockControllType> typedQuery = this.em.createQuery(q);
        try {
            value = typedQuery.getSingleResult();
            if (value != null) {
                if (value.getServerIpAddress().equals(this.hostAddress)) {
                    lockedByThisServer = true;
                }
                this.logger.debug(" isLockedByThisServer# {} opeation {} {} locked by: {} {}",
                        new Object[] { lockedByThisServer, operation.getUUID(), operation.getName(),
                                value.getServerName(), value.getLockDate() });
            }
        } catch (NoResultException e) {
            lockedByThisServer = false;
        } catch (NonUniqueResultException e) {
            lockedByThisServer = false;
        }
        return lockedByThisServer;
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#isLockedOperation(com.qpark.eip.core.spring.lockedoperation.LockableOperation)
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public synchronized boolean isLockedOperation(final LockableOperation operation) {
        this.logger.debug("+isLocked# {} {} {}",
                new Object[] { this.hostName, operation.getUUID(), operation.getName() });
        if (this.firstRun) {
            this.unlockOperationOnServerStart();
            this.firstRun = false;
        }
        boolean locked = false;
        String logString = getOperationLockString(operation);
        OperationLockControllType value = null;
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<OperationLockControllType> q = cb.createQuery(OperationLockControllType.class);
        Root<OperationLockControllType> c = q.from(OperationLockControllType.class);
        q.where(cb.equal(c.<String>get("operationName"), logString));
        TypedQuery<OperationLockControllType> typedQuery = this.em.createQuery(q);
        try {
            value = typedQuery.getSingleResult();
            if (value != null) {
                this.logger.debug(" isLocked# opeation {} {} locked by: {} {}", new Object[] { operation.getUUID(),
                        operation.getName(), value.getServerName(), value.getLockDate() });
                locked = true;
            }
        } catch (NoResultException e) {
            locked = false;
        } catch (NonUniqueResultException e) {
            locked = true;
        }
        this.logger.debug("-isLocked# {} {} {} {}", new Object[] { this.hostName, locked ? "locked" : "not locked",
                operation.getUUID(), operation.getName() });
        return locked;
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#lockOperation(com.qpark.eip.core.spring.lockedoperation.LockableOperation)
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public synchronized boolean lockOperation(final LockableOperation operation) {
        this.logger.debug("+lock# {} {} {}",
                new Object[] { this.hostName, operation.getUUID(), operation.getName() });
        if (this.firstRun) {
            this.unlockOperationOnServerStart();
            this.firstRun = false;
        }
        boolean locked = false;
        String logString = getOperationLockString(operation);
        OperationLockControllType value = null;
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<OperationLockControllType> q = cb.createQuery(OperationLockControllType.class);
        Root<OperationLockControllType> c = q.from(OperationLockControllType.class);
        q.where(cb.equal(c.<String>get("operationName"), logString));
        TypedQuery<OperationLockControllType> typedQuery = this.em.createQuery(q);
        try {
            value = typedQuery.getSingleResult();
            this.logger.debug(" lock# opeation {} {} locked by: {} {}", new Object[] { operation.getUUID(),
                    operation.getName(), value.getServerName(), value.getLockDate() });
        } catch (NoResultException e) {
            value = null;
        } catch (NonUniqueResultException e) {
            return false;
        }
        if (value == null) {
            value = new OperationLockControllType();
            value.setOperationName(logString);
            value.setServerName(this.hostName);
            value.setServerIpAddress(this.hostAddress);
            value.setLockDate(DateUtil.get(new Date()));
            this.em.persist(value);
            locked = true;
        }
        this.logger.debug("-lock# {} {} {} {}", new Object[] { this.hostName, locked ? "locked" : "not locked",
                operation.getUUID(), operation.getName() });
        return locked;
    }

    /**
     * Remove left over locks of previously stopped processes.
     *
     * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public void onApplicationEvent(final ContextRefreshedEvent event) {
        this.setupHostValues();
        this.logger.debug("Host name    : {}", this.hostName);
        this.logger.debug("Host address : {}", this.hostAddress);
        if (this.firstRun) {
            this.unlockOperationOnServerStart();
            this.firstRun = false;
        }
    }

    /**
     * @param hostAddress
     *            the hostAddress to set
     */
    public void setHostAddress(final String hostAddress) {
        this.hostAddress = hostAddress;
    }

    /**
     * @param hostName
     *            the hostName to set
     */
    public void setHostName(final String hostName) {
        this.hostName = hostName;
    }

    private void setupHostValues() {
        if (this.hostName == null) {
            try {
                InetAddress localaddr = InetAddress.getLocalHost();
                this.hostAddress = localaddr.getHostAddress();
                this.hostName = localaddr.getHostName();
            } catch (UnknownHostException e) {
                this.logger.error(e.getMessage(), e);
                this.hostName = "localhost";
            }
        }
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#unlockOperation(com.qpark.eip.core.spring.lockedoperation.LockableOperation)
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public boolean unlockOperation(final LockableOperation operation) {
        this.logger.debug("+unlock# {} {} {}",
                new Object[] { this.hostName, operation.getUUID(), operation.getName() });
        boolean unlocked = false;
        String logString = getOperationLockString(operation);
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<OperationLockControllType> q = cb.createQuery(OperationLockControllType.class);
        Root<OperationLockControllType> c = q.from(OperationLockControllType.class);
        q.where(cb.equal(c.<String>get("operationName"), logString));
        TypedQuery<OperationLockControllType> typedQuery = this.em.createQuery(q);
        try {
            List<OperationLockControllType> locks = typedQuery.getResultList();
            for (OperationLockControllType lock : locks) {
                this.em.remove(this.em.merge(lock));
            }
            unlocked = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            this.logger.debug("-unlock# {} {} {} {}", new Object[] { this.hostName,
                    unlocked ? "unlocked" : "not unlocked", operation.getUUID(), operation.getName() });
        }
        return unlocked;
    }

    /**
     * @see com.qpark.eip.core.spring.lockedoperation.dao.LockableOperationDao#unlockOperationOnServerStart()
     */
    @Override
    @Transactional(value = EipLockedoperationConfig.TRANSACTION_MANAGER_NAME, propagation = Propagation.REQUIRED)
    public void unlockOperationOnServerStart() {
        CriteriaBuilder cb = this.em.getCriteriaBuilder();
        CriteriaQuery<OperationLockControllType> q = cb.createQuery(OperationLockControllType.class);
        Root<OperationLockControllType> c = q.from(OperationLockControllType.class);
        q.where(cb.equal(c.<String>get("serverName"), this.hostName));
        TypedQuery<OperationLockControllType> typedQuery = this.em.createQuery(q);
        try {
            List<OperationLockControllType> locks = typedQuery.getResultList();
            for (OperationLockControllType lock : locks) {
                this.logger.debug(" remove lock on server start (this {}): {} {}", this.hostName,
                        lock.getServerName(), lock.getLockDate());
                this.em.remove(this.em.merge(lock));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}