/******************************************************************************* * Copyright 2017 Graz University of Technology * EAAF-Core Components has been developed in a cooperation between EGIZ, * A-SIT Plus, A-SIT, and Graz University of Technology. * * Licensed under the EUPL, Version 1.2 or - as soon they will be approved by * the European Commission - subsequent versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * https://joinup.ec.europa.eu/news/understanding-eupl-v12 * * Unless required by applicable law or agreed to in writing, software * distributed under the Licence is distributed on an "AS IS" basis, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the Licence for the specific language governing permissions and * limitations under the Licence. * * This product combines work with different licenses. See the "NOTICE" text * file for details on the various modules and licenses. * The "NOTICE" text file is part of the distribution. Any derivative works * that you distribute must include a readable copy of the "NOTICE" text file. *******************************************************************************/ /******************************************************************************* *******************************************************************************/ /******************************************************************************* *******************************************************************************/ package at.gv.egiz.eaaf.core.impl.idp.auth; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import at.gv.egiz.eaaf.core.api.IRequest; import at.gv.egiz.eaaf.core.api.IRequestStorage; import at.gv.egiz.eaaf.core.api.idp.process.ProcessInstanceStoreDAO; import at.gv.egiz.eaaf.core.api.storage.ITransactionStorage; import at.gv.egiz.eaaf.core.api.utils.IPendingRequestIdGenerationStrategy; import at.gv.egiz.eaaf.core.exceptions.EAAFException; import at.gv.egiz.eaaf.core.exceptions.EAAFStorageException; import at.gv.egiz.eaaf.core.exceptions.PendingReqIdValidationException; import at.gv.egiz.eaaf.core.impl.idp.controller.protocols.RequestImpl; import at.gv.egiz.eaaf.core.impl.utils.TransactionIDUtils; @Service("RequestStorage") public class RequestStorage implements IRequestStorage{ private static final Logger log = LoggerFactory.getLogger(RequestStorage.class); @Autowired(required=true) ITransactionStorage transactionStorage; @Autowired(required=true) ProcessInstanceStoreDAO processInstanceStore; @Autowired(required=true) IPendingRequestIdGenerationStrategy pendingReqIdGenerationStrategy; @Override public IRequest getPendingRequest(String pendingReqID) throws PendingReqIdValidationException { try { final String internalPendingReqId = pendingReqIdGenerationStrategy.validateAndGetPendingRequestId(pendingReqID); log.debug("PendingReqId is valid"); //get pending-request from storage final IRequest pendingRequest = getInternalPendingRequest(internalPendingReqId); //set transactionID and sessionID to Logger TransactionIDUtils.setAllLoggingVariables(pendingRequest); return pendingRequest; } catch (final PendingReqIdValidationException e) { log.info("PendingRequestId is invalid. Reason: {} ", e.getMessage()); // search invalid pending-request for errorHandling IRequest invalidPendingRequest = null; try { if (StringUtils.isNotEmpty(e.getInvalidInternalPendingReqId())) invalidPendingRequest = transactionStorage.get(e.getInvalidInternalPendingReqId(), IRequest.class); } catch (final EAAFException e1) { log.info("No PendingRequst found with pendingRequestID " + pendingReqID); return null; } e.setInvalidPendingReq(invalidPendingRequest); throw e; } catch (EAAFException | NullPointerException e) { log.info("No PendingRequst found with pendingRequestID " + pendingReqID); return null; } } @Override public void storePendingRequest(IRequest pendingRequest) throws EAAFException { try { if (pendingRequest instanceof IRequest) { try { //validate pending-requestId final String internalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId()); //store pending request transactionStorage.put(internalPendingRequestId, pendingRequest, -1); } catch (final PendingReqIdValidationException e) { log.warn("Invalid pending-request-Id. Reason: {}", e.getMessage()); log.warn("Do NOT store pending-request with invalid pending-request-Id. The process will break soon!"); } } else throw new EAAFException("PendigRequest is NOT of type 'IRequest'", null); } catch (final EAAFException e) { log.warn("PendingRequest with ID=" + pendingRequest.getPendingRequestId() + " can not stored.", e); throw new EAAFStorageException("PendingRequest with Id: " + pendingRequest.getPendingRequestId() + " can not be stored", e); } } @Override public void removePendingRequest(String pendingReqID) { if (pendingReqID != null) { String internalPendingReqId = null; try { internalPendingReqId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingReqID); } catch (final PendingReqIdValidationException e) { internalPendingReqId = e.getInvalidInternalPendingReqId(); } try { //remove process-management execution instance# if (internalPendingReqId != null) { final IRequest pendingReq = getInternalPendingRequest(internalPendingReqId); if (pendingReq != null && pendingReq.getProcessInstanceId() != null) processInstanceStore.remove(pendingReq.getProcessInstanceId()); //remove pending-request transactionStorage.remove(internalPendingReqId); } } catch (final EAAFException e) { log.warn("Removing process associated with pending-request:" + pendingReqID + " FAILED.", e); } } } /* (non-Javadoc) * @see at.gv.egovernment.moa.id.storage.IRequestStorage#changePendingRequestID(at.gv.egovernment.moa.id.moduls.IRequest) */ @Override public String changePendingRequestID(IRequest pendingRequest) throws EAAFException { if (pendingRequest instanceof RequestImpl) { //get old internal pendingReqId String oldInternalRequestID = null; try { oldInternalRequestID = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(pendingRequest.getPendingRequestId()); } catch (final PendingReqIdValidationException e) { //it's no problem, because it must be valid before when pending-request was loaded and we change it now oldInternalRequestID = e.getInvalidInternalPendingReqId(); } //generate new pendingReqId and get internalPendingReqId final String newRequestID = pendingReqIdGenerationStrategy.generateExternalPendingRequestId(); ((RequestImpl)pendingRequest).setPendingRequestId(newRequestID); String newInternalPendingRequestId = null; try { newInternalPendingRequestId = pendingReqIdGenerationStrategy.getPendingRequestIdWithOutChecks(newRequestID); } catch (final PendingReqIdValidationException e) { throw new EAAFException("internal.99", new Object[]{"Generate invalid pendingRequestId. Something looks WRONG"}, e); } //change Key in cache log.debug("Change pendingRequestID from " + pendingRequest.getPendingRequestId() + " to " + newRequestID); transactionStorage.changeKey(oldInternalRequestID, newInternalPendingRequestId, pendingRequest); //only delete oldRequestID, no change. return newRequestID; } else { log.error("PendingRequest object is not of type 'RequestImpl.class'"); throw new EAAFException("PendingRequest object is not of type 'RequestImpl.class'", null); } } private IRequest getInternalPendingRequest(String internalPendingReqId) throws EAAFException { final IRequest pendingRequest = transactionStorage.get(internalPendingReqId, IRequest.class); if (pendingRequest == null) { log.info("No PendingRequst found with pendingRequestID " + internalPendingReqId); return null; } return pendingRequest; } }