Skip to content
Snippets Groups Projects
Commit 8d1fdaec authored by jakubs's avatar jakubs
Browse files

BIS-172 propagate service conversations to entity validation interceptor via thread locals

SVN: 26570
parent 51b57f4d
No related branches found
No related tags found
No related merge requests found
......@@ -81,6 +81,7 @@ import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDataStoreDAO;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.IEntityTypeDAO;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.IPersonDAO;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.ISampleTypeDAO;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.ServiceConversationsThreadContext;
import ch.systemsx.cisd.openbis.generic.shared.IDataStoreService;
import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSService;
import ch.systemsx.cisd.openbis.generic.shared.IETLLIMSServiceConversational;
......@@ -1454,6 +1455,8 @@ public class ETLService extends AbstractCommonServer<IETLLIMSService> implements
injectPerson(sessionForEntityOperation, userId);
}
ServiceConversationsThreadContext.setProgressListener(progressListener);
long spacesCreated =
createSpaces(sessionForEntityOperation, operationDetails, progressListener);
......
/*
* Copyright 2012 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.generic.server.dataaccess;
import ch.systemsx.cisd.common.conversation.IProgressListener;
/**
* The class contains the logic for communication beetween Hibernate interceptors, which should send
* service conversation updates, and parts of applications that use service conversations, but don't
* have acces to the Hibernate objects.
* <p>
* It lets the owner of service conversation store the information about it in the thread local
* variable, from which the interceptor can later read it.
*
* @author Jakub Straszewski
*/
public class ServiceConversationsThreadContext
{
private static ThreadLocal<IProgressListener> progressListener;
static
{
progressListener = new ThreadLocal<IProgressListener>();
}
/**
* Store progress listener in a thread local context
*/
public static void setProgressListener(IProgressListener listener)
{
progressListener.set(listener);
}
/**
* Remove information about progress listener from the thread local context.
*/
public static void unsetProgressListener()
{
progressListener.remove();
}
/**
* Read the progress listener from the thread local context
*/
public static IProgressListener getProgressListener()
{
return progressListener.get();
}
}
......@@ -27,8 +27,10 @@ import org.hibernate.Interceptor;
import org.hibernate.Transaction;
import org.hibernate.type.Type;
import ch.systemsx.cisd.common.conversation.IProgressListener;
import ch.systemsx.cisd.common.exceptions.UserFailureException;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.IDAOFactory;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.ServiceConversationsThreadContext;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.dynamic_property.DynamicPropertyEvaluator;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.dynamic_property.IDynamicPropertyEvaluator;
import ch.systemsx.cisd.openbis.generic.server.dataaccess.dynamic_property.calculator.EntityAdaptorFactory;
......@@ -61,6 +63,10 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
this.callback = callback;
this.daoFactory = daoFactory;
initializeLists();
totalEntitiesToValidateCount = 0;
entitiesValidatedCount = 0;
}
IHibernateTransactionManagerCallback callback;
......@@ -80,10 +86,25 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
Queue<IEntityInformationWithPropertiesHolder> entitiesToValidate;
/**
* WE get information about progress listener, form the caller of updates. Luckily the
* onFlushDirty and onSave hooks are executed in the same thread as the caller.
* <p>
* The beforeTransactionCompletionHook is called in the separate thread, therefore we persist
* progress listener in a designated variable
*/
IProgressListener progressListener;
int totalEntitiesToValidateCount;
int entitiesValidatedCount;
@Override
public boolean onSave(Object entity, Serializable id, Object[] state, String[] propertyNames,
Type[] types)
{
updateListener();
if (entity instanceof IEntityInformationWithPropertiesHolder)
{
newEntity((IEntityInformationWithPropertiesHolder) entity);
......@@ -91,10 +112,17 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
return false;
}
private void updateListener()
{
progressListener = ServiceConversationsThreadContext.getProgressListener();
}
@Override
public boolean onFlushDirty(Object entity, Serializable id, Object[] currentState,
Object[] previousState, String[] propertyNames, Type[] types)
{
updateListener();
if (entity instanceof IEntityInformationWithPropertiesHolder)
{
modifiedEntity((IEntityInformationWithPropertiesHolder) entity);
......@@ -143,15 +171,18 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
IEntityInformationWithPropertiesHolder entity, boolean isNewEntity)
{
String result = null;
try
{
if (progressListener != null)
{
progressListener.update("Validation of entities", totalEntitiesToValidateCount,
entitiesValidatedCount);
}
result = calculate(script, entity, isNewEntity);
} catch (Throwable e)
{
callback.rollbackTransaction(tx, "Validation of " + entityDescription(entity)
+ " resulted in error. " + e.getMessage());
e.printStackTrace();
}
if (result != null)
{
......@@ -181,11 +212,13 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
private void newEntity(IEntityInformationWithPropertiesHolder entity)
{
totalEntitiesToValidateCount++;
newEntities.add(entity);
}
private void validatedEntity(IEntityInformationWithPropertiesHolder entity)
{
entitiesValidatedCount++;
validatedEntities.add(entity);
}
......@@ -193,6 +226,7 @@ public class EntityValidationInterceptor extends EmptyInterceptor implements
{
if (false == newEntities.contains(entity))
{
totalEntitiesToValidateCount++;
modifiedEntities.add(entity);
}
}
......
......@@ -139,7 +139,7 @@ public final class EntityTypeDAOTest extends AbstractDAOTest
public final void testListMaterialTypes()
{
final IEntityTypeDAO entityTypeDAO = daoFactory.getEntityTypeDAO(EntityKind.MATERIAL);
assertEquals(8, entityTypeDAO.listEntityTypes().size());
assertEquals(9, entityTypeDAO.listEntityTypes().size());
}
@Test(dependsOnMethods = "testListMaterialTypes")
......
......@@ -16,3 +16,5 @@
22 6 15 f f 2008-11-05 09:18:32.512+01 2 \N 2 \N t
23 8 1 t t 2008-11-05 09:18:32.512+01 2 \N 1 \N t
24 8 26 f f 2012-03-13 09:18:32.512+01 2 \N 2 \N t
25 9 2 t t 2008-11-05 09:18:00.622+01 1 \N 1 \N t
26 9 1 f t 2008-11-05 09:18:00.622+01 1 \N 2 \N t
\ No newline at end of file
1 VIRUS Virus 1 2009-03-23 15:34:44.462776+01 \N
2 CELL_LINE Cell Line or Cell Culture. The growing of cells under controlled conditions. 1 2009-03-23 15:34:44.462776+01 \N
3 GENE Gene 1 2009-03-23 15:34:44.462776+01 \N
5 CONTROL Control of a control layout 1 2009-03-23 15:34:44.462776+01 \N
5 CONTROL Control of a control layout 1 2009-03-23 15:34:44.462776+01 5
6 BACTERIUM Bacterium 1 2009-03-23 15:34:44.462776+01 \N
7 COMPOUND Compound 1 2009-03-23 15:34:44.462776+01 \N
4 SIRNA Oligo nucleotide 1 2009-03-23 15:34:44.462776+01 \N
8 SELF_REF Self Referencing Material 1 2012-03-13 15:34:44.462776+01 \N
9 SLOW_GENE Slowly validating material 1 2009-03-23 15:34:44.462776+01 10
......@@ -7,3 +7,4 @@
7 1 validateUpdateFAIL \N def validate(entity, isNew):\n if (not isNew):\n return "Cannot update this entity"\n 2010-10-27 15:16:48.994831+02 2 \N ENTITY_VALIDATION
8 1 validateChildren \N def validate(entity, isNew):\n for childRelation in entity.entityPE().getChildRelationships():\n requestValidation(childRelation.getChildSample()) 2010-10-27 15:16:48.994831+02 2 \N ENTITY_VALIDATION
9 1 code_date \N "%s %s" % (entity.code(), str(currentDate().getTime())) 2010-10-27 15:16:48.994831+02 2 \N DYNAMIC_PROPERTY
10 1 waitOK \N import time;\ndef validate(entity, isNew):\n time.sleep(1);\n 2010-10-27 15:16:48.994831+02 2 \N ENTITY_VALIDATION
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment