/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package com.smartitengineering.user.service.impl.hbase; import com.google.inject.Inject; import com.smartitengineering.common.dao.search.CommonFreeTextSearchDao; import com.smartitengineering.dao.common.CommonReadDao; import com.smartitengineering.dao.common.CommonWriteDao; import com.smartitengineering.dao.common.queryparam.QueryParameterFactory; import com.smartitengineering.dao.impl.hbase.spi.RowCellIncrementor; import com.smartitengineering.user.domain.SecuredObject; import com.smartitengineering.user.domain.UniqueConstrainedField; import com.smartitengineering.user.observer.CRUDObservable; import com.smartitengineering.user.observer.ObserverNotification; import com.smartitengineering.user.service.ExceptionMessage; import com.smartitengineering.user.service.SecuredObjectService; import com.smartitengineering.user.service.impl.hbase.domain.AutoId; import com.smartitengineering.user.service.impl.hbase.domain.KeyableObject; import com.smartitengineering.user.service.impl.hbase.domain.UniqueKey; import com.smartitengineering.user.service.impl.hbase.domain.UniqueKeyIndex; import java.util.Collection; import java.util.Date; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.solr.client.solrj.util.ClientUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * * @author imyousuf */ public class SecuredObjectServiceImpl implements SecuredObjectService { @Inject private CommonWriteDao<SecuredObject> writeDao; @Inject private CommonReadDao<SecuredObject, Long> readDao; @Inject private CommonWriteDao<UniqueKeyIndex> uniqueKeyIndexWriteDao; @Inject private CommonReadDao<UniqueKeyIndex, UniqueKey> uniqueKeyIndexReadDao; @Inject private CommonWriteDao<AutoId> autoIdWriteDao; @Inject private CommonReadDao<AutoId, String> autoIdReadDao; @Inject private CRUDObservable observable; @Inject protected CommonFreeTextSearchDao<SecuredObject> freeTextSearchDao; @Inject private RowCellIncrementor<SecuredObject, AutoId, String> idIncrementor; private boolean autoIdInitialized = false; protected transient Logger logger = LoggerFactory.getLogger(getClass()); protected boolean checkAndInitializeAutoId(String autoId) throws RuntimeException { AutoId id = autoIdReadDao.getById(autoId); if (id == null) { id = new AutoId(); id.setValue(Long.MAX_VALUE); id.setId(autoId); try { autoIdWriteDao.save(id); return true; } catch (RuntimeException ex) { logger.error("Could not initialize secured object auto id!", ex); throw ex; } } else { return true; } } protected void checkAndInitializeAutoId() { if (!autoIdInitialized) { autoIdInitialized = checkAndInitializeAutoId(KeyableObject.SECURED_OBJECT.name()); } } protected UniqueKey getUniqueKeyOfIndexForSecObjName(SecuredObject securedObject) { final String name = securedObject.getName(); return getUniqueKeyOfIndexForName(name, securedObject.getOrganization().getUniqueShortName()); } protected UniqueKey getUniqueKeyOfIndexForName(final String name, final String orgShortName) { UniqueKey key = new UniqueKey(); key.setKey(new StringBuilder("name_").append(name).toString()); key.setObject(KeyableObject.SECURED_OBJECT); key.setOrgId(orgShortName); return key; } protected UniqueKey getUniqueKeyOfIndexForSecObjObjId(SecuredObject securedObject) { final String objectId = securedObject.getObjectID(); return getUniqueKeyOfIndexForObjId(objectId, securedObject.getOrganization().getUniqueShortName()); } protected UniqueKey getUniqueKeyOfIndexForObjId(final String objId, final String orgShortName) { UniqueKey key = new UniqueKey(); key.setKey(new StringBuilder("objId_").append(objId).toString()); key.setObject(KeyableObject.SECURED_OBJECT); key.setOrgId(orgShortName); return key; } @Override public void save(SecuredObject securedObject) { checkAndInitializeAutoId(); validateSecuredObject(securedObject); final Date date = new Date(); securedObject.setCreationDate(date); securedObject.setLastModifiedDate(date); try { long nextId = idIncrementor.incrementAndGet(KeyableObject.SECURED_OBJECT.name(), -1l); UniqueKey key = getUniqueKeyOfIndexForSecObjName(securedObject); UniqueKeyIndex index = new UniqueKeyIndex(); index.setObjId(String.valueOf(nextId)); index.setId(key); uniqueKeyIndexWriteDao.save(index); key = getUniqueKeyOfIndexForSecObjObjId(securedObject); index = new UniqueKeyIndex(); index.setObjId(String.valueOf(nextId)); index.setId(key); uniqueKeyIndexWriteDao.save(index); securedObject.setId(nextId); writeDao.save(securedObject); observable.notifyObserver(ObserverNotification.CREATE_SECURED_OBJECT, securedObject); } catch (IllegalArgumentException e) { String message = ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_OBJECT_ID; throw new RuntimeException(message, e); } catch (Exception e) { String message = ExceptionMessage.STALE_OBJECT_STATE_EXCEPTION.name() + "-" + UniqueConstrainedField.OTHER; throw new RuntimeException(message, e); } } @Override public void update(SecuredObject securedObject) { if (securedObject.getId() == null) { throw new IllegalArgumentException("ID of SecuredObject not set to be updated!"); } final Date date = new Date(); securedObject.setLastModifiedDate(date); validateSecuredObject(securedObject); SecuredObject oldSecuredObject = readDao.getById(securedObject.getId()); if (oldSecuredObject == null) { throw new IllegalArgumentException("Trying to update non-existent secured object!"); } securedObject.setCreationDate(oldSecuredObject.getCreationDate()); try { if (!securedObject.getName().equals(oldSecuredObject.getName())) { final UniqueKey oldIndexKey = getUniqueKeyOfIndexForSecObjName(oldSecuredObject); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(oldIndexKey); if (index == null) { index = new UniqueKeyIndex(); index.setId(oldIndexKey); index.setObjId(String.valueOf(securedObject.getId())); } uniqueKeyIndexWriteDao.delete(index); index.setId(getUniqueKeyOfIndexForSecObjName(securedObject)); uniqueKeyIndexWriteDao.save(index); } if (!securedObject.getObjectID().equals(oldSecuredObject.getObjectID())) { final UniqueKey oldIndexKey = getUniqueKeyOfIndexForSecObjObjId(oldSecuredObject); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(oldIndexKey); if (index == null) { index = new UniqueKeyIndex(); index.setId(oldIndexKey); index.setObjId(String.valueOf(securedObject.getId())); } uniqueKeyIndexWriteDao.delete(index); index.setId(getUniqueKeyOfIndexForSecObjObjId(securedObject)); uniqueKeyIndexWriteDao.save(index); } writeDao.update(securedObject); observable.notifyObserver(ObserverNotification.UPDATE_SECURED_OBJECT, securedObject); } catch (IllegalArgumentException e) { String message = ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_NAME; throw new RuntimeException(message, e); } catch (Exception e) { String message = ExceptionMessage.STALE_OBJECT_STATE_EXCEPTION.name() + "-" + UniqueConstrainedField.OTHER; throw new RuntimeException(message, e); } } @Override public void delete(SecuredObject securedObject) { try { observable.notifyObserver(ObserverNotification.DELETE_SECURED_OBJECT, securedObject); writeDao.delete(securedObject); UniqueKey indexKey = getUniqueKeyOfIndexForSecObjName(securedObject); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(indexKey); if (index != null) { uniqueKeyIndexWriteDao.delete(index); } indexKey = getUniqueKeyOfIndexForSecObjObjId(securedObject); index = uniqueKeyIndexReadDao.getById(indexKey); if (index != null) { uniqueKeyIndexWriteDao.delete(index); } } catch (Exception e) { String message = ExceptionMessage.STALE_OBJECT_STATE_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_OBJECT_ID; throw new RuntimeException(message, e); } } @Override public SecuredObject getById(Long id) { return readDao.getById(id); } @Override public Collection<SecuredObject> getByOrganization(String organizationName) { StringBuilder q = new StringBuilder(); q.append("id: ").append("securedObject\\:").append("*"); q.append(" AND ").append(" organizationUniqueShortName: ").append(organizationName).append('*'); return freeTextSearchDao.search(QueryParameterFactory.getStringLikePropertyParam("q", q.toString()), QueryParameterFactory. getOrderByParam("organization", com.smartitengineering.dao.common.queryparam.Order.valueOf("ASC"))); } @Override public SecuredObject getByOrganizationAndObjectID(String organizationName, String objectID) { UniqueKey uniqueKey = getUniqueKeyOfIndexForObjId(objectID, organizationName); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(uniqueKey); if (index != null) { long securedObjectId = NumberUtils.toLong(index.getObjId(), Long.MIN_VALUE); if (securedObjectId > Long.MIN_VALUE) { return getById(securedObjectId); } } return null; } @Override public SecuredObject getByOrganizationAndName(String organizationName, String name) { UniqueKey uniqueKey = getUniqueKeyOfIndexForName(name, organizationName); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(uniqueKey); if (index != null) { long securedObjectId = NumberUtils.toLong(index.getObjId(), Long.MIN_VALUE); if (securedObjectId > Long.MIN_VALUE) { return getById(securedObjectId); } } return null; } @Override public void validateSecuredObject(SecuredObject securedObject) { if (StringUtils.isBlank(securedObject.getObjectID())) { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_OBJECT_ID. name()); } UniqueKey key = getUniqueKeyOfIndexForSecObjObjId(securedObject); UniqueKeyIndex index = uniqueKeyIndexReadDao.getById(key); if (index == null) { return; } if (securedObject.getId() != null) { if (!String.valueOf(securedObject.getId()).equals(index.getObjId())) { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_OBJECT_ID. name()); } } else { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_OBJECT_ID. name()); } //Check name is unique too if (StringUtils.isBlank(securedObject.getName())) { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_NAME. name()); } key = getUniqueKeyOfIndexForSecObjName(securedObject); index = uniqueKeyIndexReadDao.getById(key); if (index == null) { return; } if (securedObject.getId() != null) { if (!String.valueOf(securedObject.getId()).equals(index.getObjId())) { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_NAME. name()); } } else { throw new RuntimeException(ExceptionMessage.CONSTRAINT_VIOLATION_EXCEPTION.name() + "-" + UniqueConstrainedField.SECURED_OBJECT_NAME. name()); } } }