/* * Copyright (c) 2005-2011, Fraunhofer-Gesellschaft * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: * * (1) Redistributions of source code must retain the above copyright * notice, this list of conditions and the disclaimer at the end. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * (2) Neither the name of Fraunhofer nor the names of its * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * DISCLAIMER * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ package org.ogf.graap.wsag.server.persistence.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.text.MessageFormat; import java.util.Collection; import java.util.Iterator; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityManager; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.NoResultException; import javax.persistence.Query; import javax.persistence.RollbackException; import javax.persistence.Table; import javax.persistence.Transient; import javax.persistence.UniqueConstraint; import org.apache.log4j.Logger; import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlOptions; import org.ogf.graap.wsag.api.Agreement; import org.ogf.graap.wsag.api.exceptions.AgreementFactoryException; import org.ogf.graap.wsag.api.logging.LogMessage; import org.ogf.graap.wsag.server.persistence.EmfRegistry; import org.ogf.graap.wsag4j.types.engine.PersistenceAgreementContextDocument; import org.ogf.graap.wsag4j.types.engine.PersistenceAgreementContextType; import org.ogf.schemas.graap.wsAgreement.AgreementPropertiesType; import org.ogf.schemas.graap.wsAgreement.AgreementStateType; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; import eu.betaas.taas.bigdatamanager.database.service.IBigDataDatabaseService; import eu.betaas.taas.qosmanager.negotiation.NegotiationActivator; import eu.betaas.taas.bigdatamanager.database.hibernate.data.PersistentAgreementContainerDatabase; /* * TODO: the container should implement the CRUD operations * - the context element should be a transient XmlBean. * - the context element should be de/serialized on the * CRUD operation invocation */ /** * Entity class for the agreement persistence. It defines the entity fields (the tables' columns), the * named-queries used to access the stored data, and the corresponding getter/setter methods. * * @author T.Weuffel */ public class PersistentAgreementContainer extends PersistentAgreementContainerDatabase { // the logger should not be persisted private static final Logger LOG = Logger.getLogger( PersistentAgreementContainer.class ); private PersistenceAgreementContextDocument persistenceContext; /** * The default constructor is required by the JPA2 environment. It is used to instantiate an instance of * this entity. All values are then passed to this instance by setter-injection. */ public PersistentAgreementContainer() { persistenceContext = PersistenceAgreementContextDocument.Factory.newInstance(); persistenceContext.addNewPersistenceAgreementContext(); } public PersistentAgreementContainer(PersistentAgreementContainerDatabase a){ persistenceContext = PersistenceAgreementContextDocument.Factory.newInstance(); persistenceContext.addNewPersistenceAgreementContext(); id=a.id; agreementId=a.agreementId; agreementFactoryId=a.agreementFactoryId; state=a.state; agreementClassName=a.agreementClassName; persistedAgreementContextType=a.persistedAgreementContextType; } /** * Creates a new {@link PersistentAgreementContainer} for the given agreement and agreement factory id. * * @param agreement * the agreement for which the container will be created * @param factoryId * the id of the factory that created the agreement */ public PersistentAgreementContainer( Agreement agreement, String factoryId ) { agreementFactoryId = factoryId; // build wrapper persistenceContext = PersistenceAgreementContextDocument.Factory.newInstance(); PersistenceAgreementContextType context = persistenceContext.addNewPersistenceAgreementContext(); // store agreement properties context.addNewAgreementProperties(); // store the whole agreement context itself PersistenceAgreementContextType.Entry entry = context.addNewEntry(); entry.setValue( agreement.getContext() ); entry.setName( DatabasePersistentAgreement.AGREEMENT_CONTEXT_ENTRY ); // store the agreement properties entry = context.addNewEntry(); entry.setValue( agreement.getXMLObject() ); entry.setName( DatabasePersistentAgreement.AGREEMENT_PROPERTIES_ENTRY ); context.getAgreementProperties().set( agreement.getXMLObject() ); // set agreement class name setAgreementClassName( agreement.getImplementationClass().getName() ); // set the current agreements' state and EPR setState( agreement.getState() ); // // initial serialization of the xml object // this.persistedAgreementContextType = persistenceContext.xmlText(); } /** * * @return the agreement id */ public String getAgreementId() { return agreementId; } /** * * @return the agreement factory id */ public String getAgreementFactoryId() { return agreementFactoryId; } /** * * @param agreementFactoryId * the factory id to set */ public void setAgreementFactoryId( String agreementFactoryId ) { this.agreementFactoryId = agreementFactoryId; } /** * * @return the agreement state */ public AgreementStateType getState() { AgreementPropertiesType props = persistenceContext.getPersistenceAgreementContext().getAgreementProperties(); return props.getAgreementState(); } /** * * @param state * the agreement state to set */ public void setState( AgreementStateType state ) { AgreementPropertiesType props = persistenceContext.getPersistenceAgreementContext().getAgreementProperties(); props.setAgreementState( state ); this.state = state.getState().toString(); } /** * * @return the agreement implementation class name */ public String getAgreementClassName() { return agreementClassName; } /** * * @param agreementClassName * the agreement implementation class name to set */ public void setAgreementClassName( String agreementClassName ) { this.agreementClassName = agreementClassName; } /** * * @return the context of the persistent agreement */ public PersistenceAgreementContextType getPersistedAgreementContextType() { return persistenceContext.getPersistenceAgreementContext(); } /** * * @param persistenceAgreementContextType * the context of the persistent agreement to set */ public void setPersistedAgreementContextType( PersistenceAgreementContextType persistenceAgreementContextType ) { this.persistenceContext.getPersistenceAgreementContext().set( persistenceAgreementContextType ); this.persistedAgreementContextType = persistenceContext.xmlText(); } /** * Creates a new persistent container that stores the agreement properties document and the agreement * execution context. * * @param agreement * the agreement * * @param factoryId * the id of the factory that created the agreement * * @return the persistent container * * @throws AgreementFactoryException * indicates that the persistent container could not be created */ public static PersistentAgreementContainer createContainer( Agreement agreement, String factoryId ) throws AgreementFactoryException { LOG.debug( "Create new PersistentAgreementContainer " + factoryId ); PersistentAgreementContainer container = new PersistentAgreementContainer( agreement, factoryId ); // // serialize xml object // container.persistedAgreementContextType = container.persistenceContext.xmlText(); // try to persist the wrapped agreement EntityManager em = EmfRegistry.getEntityManager(); try { synchronized ( agreement ) { em.getTransaction().begin(); try { LOG.info( "original agreement id: " + container.getAgreementId() + " " + container.getId() ); // persist and commit em.persist( container ); em.getTransaction().commit(); String agreementId = container.getAgreementId(); LOG.info( "generated agreement id: " + agreementId + " " + container.getId() ); } catch ( RollbackException ex ) { LOG.error( MessageFormat.format( "Could not persist the wrapped agreement with id ''{0}''.", agreement.getAgreementId() ), ex ); // roll back the persistment em.getTransaction().rollback(); throw new AgreementFactoryException( MessageFormat.format( "Could not persist the wrapped agreement with id ''{0}''.", agreement.getAgreementId() ) ); } // TODO: check if this can be done in one transaction // // update generated agreement ids // em.getTransaction().begin(); try { // // update agreement id and serialize xml object // AgreementPropertiesType properties = container.persistenceContext.getPersistenceAgreementContext() .getAgreementProperties(); properties.setAgreementId( container.getAgreementId() ); agreement.setAgreementId( container.getAgreementId() ); container.persistedAgreementContextType = container.persistenceContext.xmlText(); em.merge( container ); em.getTransaction().commit(); LOG.trace( "updated agreement id: " + container.getAgreementId() ); } catch ( RollbackException ex ) { LOG.error( LogMessage.getMessage( "Could not persist the wrapped agreement with id ''{0}''.", agreement.getAgreementId() ), ex ); // roll back the persistment em.getTransaction().rollback(); String message = "Failed to update persistence context ''{0}'' with generated id."; String error = MessageFormat.format( message, new Object[] { agreement.getAgreementId() } ); throw new AgreementFactoryException( error ); } } } finally { em.close(); } return container; } /** * Loads a persistent container for the given agreement id and agreement factory id. * * @param agreementId * the id of the agreement to load * @param agreementFactoryId * the id of the factory that created the agreement * @return the persistent container * * @throws AgreementFactoryException * indicates that the agreement could not be loaded */ public static PersistentAgreementContainer loadContainer( String agreementId, String agreementFactoryId ) throws AgreementFactoryException { // // load the persisted agreement // EntityManager em = EmfRegistry.getEntityManager(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findByAgreementId" ); query.setParameter( "agreementId", agreementId ); try { PersistentAgreementContainer container = (PersistentAgreementContainer) query.getSingleResult(); try { String xml = container.persistedAgreementContextType; container.persistenceContext = (PersistenceAgreementContextDocument) XmlObject.Factory.parse( xml ); } catch ( XmlException ex ) { LOG.error( "could not load persisted agreement context.", ex ); throw new AgreementFactoryException( "could not load persisted agreement context.", ex ); } return container; } catch ( NoResultException ex ) { // // not found, so we return null // return null; } } finally { em.close(); } } /** * Loads a persistent container for the given agreement id and agreement factory id. * * @param agreementId * the id of the agreement to load * * @return the persistent container * * @throws AgreementFactoryException * indicates that the agreement with the given id could not be loaded */ public static PersistentAgreementContainer loadContainer( String agreementId ) throws AgreementFactoryException { // // load the persisted agreement // EntityManager em = EmfRegistry.getEntityManager(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findByAgreementId" ); query.setParameter( "agreementId", agreementId ); try { PersistentAgreementContainer persistentAgreementContainer = (PersistentAgreementContainer) query.getSingleResult(); try { String xml = persistentAgreementContainer.persistedAgreementContextType; persistentAgreementContainer.persistenceContext = (PersistenceAgreementContextDocument) XmlObject.Factory.parse( xml ); } catch ( XmlException ex ) { LOG.error( "could not load persisted agreement context.", ex ); throw new AgreementFactoryException( "could not load persisted agreement context.", ex ); } return persistentAgreementContainer; } catch ( NoResultException ex ) { // // not found, so we return null // return null; } } finally { em.close(); } } /** * Creates a list of all persistent agreement containers. * * @return the persisted containers * * @throws AgreementFactoryException * indicates an error while listing the agreement containers */ @SuppressWarnings( "unchecked" ) public static PersistentAgreementContainer[] listContainers() throws AgreementFactoryException { // // load the persisted agreement // EntityManager em = EmfRegistry.getEntityManager(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findAll" ); Collection<PersistentAgreementContainer> containers = null; try { containers = query.getResultList(); for ( Iterator<PersistentAgreementContainer> iterator = containers.iterator(); iterator.hasNext(); ) { PersistentAgreementContainer persistentAgreementContainer = iterator.next(); try { String xml = persistentAgreementContainer.persistedAgreementContextType; persistentAgreementContainer.persistenceContext = (PersistenceAgreementContextDocument) XmlObject.Factory.parse( xml ); } catch ( XmlException ex ) { LOG.error( "could not load persisted agreement context.", ex ); throw new AgreementFactoryException( "could not load persisted agreement context.", ex ); } } return containers.toArray( new PersistentAgreementContainer[containers.size()] ); } catch ( NoResultException ex ) { // // not found, so we return null // return null; } } finally { em.close(); } } /** * Lists all persistent agreement containers for a given factory * * @param agreementFactoryId * the factory id * * @return the container for the given factory id * * @throws AgreementFactoryException * indicates an error while listing the persistent containers for the given factory id */ @SuppressWarnings( "unchecked" ) public static PersistentAgreementContainer[] listContainers( String agreementFactoryId ) throws AgreementFactoryException { // // load the persisted agreement // EntityManager em = EmfRegistry.getEntityManager(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findAll" ); Collection<PersistentAgreementContainer> containers = null; try { containers = query.getResultList(); for ( Iterator<PersistentAgreementContainer> iterator = containers.iterator(); iterator.hasNext(); ) { PersistentAgreementContainer persistentAgreementContainer = iterator.next(); try { String xml = persistentAgreementContainer.persistedAgreementContextType; persistentAgreementContainer.persistenceContext = (PersistenceAgreementContextDocument) XmlObject.Factory.parse( xml ); } catch ( XmlException ex ) { LOG.error( "could not load persisted agreement context.", ex ); throw new AgreementFactoryException( "could not load persisted agreement context.", ex ); } } //LOG.error("lenght" + containersfinal.size()); return containers.toArray( new PersistentAgreementContainer[containers.size()] ); } catch ( NoResultException ex ) { // // not found, so we return null // return null; } } finally { em.close(); } } /** * Save the container instance. * * @throws AgreementFactoryException * indicates an error saving the container */ public void saveContainer() throws AgreementFactoryException { // try to persist the wrapped agreement EntityManager em = EmfRegistry.getEntityManager(); try { em.getTransaction().begin(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findByAgreementId" ); query.setParameter( "agreementId", agreementId ); PersistentAgreementContainer persistentAgreementContainer = null; try { persistentAgreementContainer = (PersistentAgreementContainer) query.getSingleResult(); } catch ( NoResultException ex ) { String error = "Persisted agreement not found in database. Update operation failed."; LOG.error( error ); throw new AgreementFactoryException( error, ex ); } // // make sure the agreement id was not changed // AgreementPropertiesType agreementProperties = persistenceContext.getPersistenceAgreementContext().getAgreementProperties(); agreementProperties.setAgreementId( agreementId ); persistentAgreementContainer.agreementClassName = agreementClassName; persistentAgreementContainer.agreementFactoryId = agreementFactoryId; persistentAgreementContainer.agreementId = agreementId; persistentAgreementContainer.id = id; persistentAgreementContainer.persistedAgreementContextType = persistenceContext.xmlText(); persistentAgreementContainer.persistenceContext = persistenceContext; persistentAgreementContainer.state = agreementProperties.getAgreementState().getState().toString(); em.merge( persistentAgreementContainer ); em.getTransaction().commit(); } catch ( Exception ex ) { LOG.error( LogMessage.getMessage( "Could not update the wrapped agreement with id ''{0}''.", getAgreementId() ), ex ); // roll back the persistment em.getTransaction().rollback(); throw new AgreementFactoryException( MessageFormat.format( "Could not persist the wrapped agreement with id ''{0}''.", getAgreementId() ) ); } } finally { em.close(); } } /** * Deletes this container instance. * * @throws AgreementFactoryException * indicates an error while deleting the container */ public void deleteContainer() throws AgreementFactoryException { // try to persist the wrapped agreement EntityManager em = EmfRegistry.getEntityManager(); try { em.getTransaction().begin(); try { Query query = em.createNamedQuery( "PersistentAgreementContainer.findByAgreementId" ); query.setParameter( "agreementId", agreementId ); try { PersistentAgreementContainer persistentAgreementContainer = (PersistentAgreementContainer) query.getSingleResult(); em.remove( persistentAgreementContainer ); } catch ( NoResultException ex ) { LOG.warn( "Persisted agreement not found in database. Remove operation skipped." ); } em.getTransaction().commit(); } catch ( Exception ex ) { LOG.error( LogMessage.getMessage( "Could not delete the wrapped agreement with id ''{0}''.", getAgreementId() ), ex ); // roll back the persistment em.getTransaction().rollback(); throw new AgreementFactoryException( MessageFormat.format( "Could not persist the wrapped agreement with id ''{0}''.", getAgreementId() ) ); } } finally { em.close(); } } /* * (non-Javadoc) * * @see java.lang.Object#toString() */ @Override public String toString() { return persistenceContext.xmlText( new XmlOptions().setSavePrettyPrint() ); } }