diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/ReliableNamedEntryPoint.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/ReliableNamedEntryPoint.java index d747a504051..9f9ae720ea6 100644 --- a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/ReliableNamedEntryPoint.java +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/ReliableNamedEntryPoint.java @@ -33,7 +33,8 @@ public ReliableNamedEntryPoint(EntryPointId entryPoint, EntryPointNode entryPoin protected ObjectStore createObjectStore(EntryPointId entryPoint, RuleBaseConfiguration conf, ReteEvaluator reteEvaluator) { boolean storesOnlyStrategy = reteEvaluator.getSessionConfiguration().getPersistedSessionOption().getPersistenceStrategy() == PersistedSessionOption.PersistenceStrategy.STORES_ONLY; return storesOnlyStrategy ? - SimpleReliableObjectStoreFactory.get().createSimpleReliableObjectStore(StorageManagerFactory.get().getStorageManager().getOrCreateStorageForSession(reteEvaluator, "ep" + getEntryPointId())) : + SimpleReliableObjectStoreFactory.get().createSimpleReliableObjectStore(StorageManagerFactory.get().getStorageManager().getOrCreateStorageForSession(reteEvaluator, "ep" + getEntryPointId()), + reteEvaluator.getSessionConfiguration().getPersistedSessionOption()) : new FullReliableObjectStore(StorageManagerFactory.get().getStorageManager().getOrCreateStorageForSession(reteEvaluator, "ep" + getEntryPointId())); } diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredObject.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredObject.java index 9495d5720a3..57a6c3c2702 100644 --- a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredObject.java +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredObject.java @@ -19,7 +19,7 @@ public class SerializableStoredObject extends BaseStoredObject { - private final Serializable object; + protected final Serializable object; public SerializableStoredObject(Object object, boolean propagated) { super(propagated); diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredRefObject.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredRefObject.java new file mode 100644 index 00000000000..1313cd25be4 --- /dev/null +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SerializableStoredRefObject.java @@ -0,0 +1,39 @@ +package org.drools.reliability.core; + +import org.drools.core.common.Storage; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + +public class SerializableStoredRefObject extends SerializableStoredObject { + + private final Map referencedObjects; + + public SerializableStoredRefObject(Object object, boolean propagated) { + super(object, propagated); + referencedObjects=new HashMap<>(); + } + + public void addReferencedObject(String fieldName, Long refObjectKey){ + this.referencedObjects.put(fieldName, refObjectKey); + } + + public StoredObject updateReferencedObjects(Storage storage){ + this.referencedObjects.keySet().forEach(fieldName -> { + Optional refField = Arrays.stream(object.getClass().getDeclaredFields()) + .filter(f -> f.getName().equals(fieldName)).findFirst(); + if (refField.isPresent()){ + refField.get().setAccessible(true); + try { + refField.get().set(this.object, storage.get(this.referencedObjects.get(refField.get().getName())).getObject()); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + }); + return this; + } +} diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleReliableObjectStoreFactory.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleReliableObjectStoreFactory.java index 3f195361382..188f90610c9 100644 --- a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleReliableObjectStoreFactory.java +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleReliableObjectStoreFactory.java @@ -17,10 +17,11 @@ import org.drools.core.common.Storage; import org.kie.api.internal.utils.KieService; +import org.kie.api.runtime.conf.PersistedSessionOption; public interface SimpleReliableObjectStoreFactory extends KieService { - SimpleReliableObjectStore createSimpleReliableObjectStore(Storage storage); + SimpleReliableObjectStore createSimpleReliableObjectStore(Storage storage, PersistedSessionOption persistedSessionOption); class Holder { diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStore.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStore.java index 24acb1c5e6d..be5b99c5555 100644 --- a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStore.java +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStore.java @@ -15,10 +15,6 @@ package org.drools.reliability.core; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - import org.drools.core.ClockType; import org.drools.core.common.DefaultEventHandle; import org.drools.core.common.IdentityObjectStore; @@ -27,9 +23,13 @@ import org.drools.core.common.InternalWorkingMemoryEntryPoint; import org.drools.core.common.Storage; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + public class SimpleSerializationReliableObjectStore extends IdentityObjectStore implements SimpleReliableObjectStore { - protected final transient Storage storage; + protected transient Storage storage; protected boolean reInitPropagated = false; @@ -113,7 +113,7 @@ public void putIntoPersistedStorage(InternalFactHandle handle, boolean propagate storage.put(getHandleForObject(object).getId(), storedObject); } - private StoredObject factHandleToStoredObject(InternalFactHandle handle, boolean propagated, Object object) { + StoredObject factHandleToStoredObject(InternalFactHandle handle, boolean propagated, Object object) { return handle.isEvent() ? createStoredEvent(propagated, object, ((DefaultEventHandle) handle).getStartTimestamp(), ((DefaultEventHandle) handle).getDuration()) : createStoredObject(propagated, object); diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStoreFactory.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStoreFactory.java index 81478de918b..aad37b71998 100644 --- a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStoreFactory.java +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableObjectStoreFactory.java @@ -16,6 +16,7 @@ package org.drools.reliability.core; import org.drools.core.common.Storage; +import org.kie.api.runtime.conf.PersistedSessionOption; public class SimpleSerializationReliableObjectStoreFactory implements SimpleReliableObjectStoreFactory { @@ -25,6 +26,14 @@ public SimpleReliableObjectStore createSimpleReliableObjectStore(Storage storage, PersistedSessionOption persistedSessionOption) { + if (persistedSessionOption.getPersistenceObjectsStrategy() == PersistedSessionOption.PersistenceObjectsStrategy.SIMPLE) { + return new SimpleSerializationReliableObjectStore(storage); + }else { + return new SimpleSerializationReliableRefObjectStore(storage); + } + } + @Override public int servicePriority() { return servicePriorityValue; diff --git a/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableRefObjectStore.java b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableRefObjectStore.java new file mode 100644 index 00000000000..71279ad7420 --- /dev/null +++ b/drools-reliability/drools-reliability-core/src/main/java/org/drools/reliability/core/SimpleSerializationReliableRefObjectStore.java @@ -0,0 +1,86 @@ +package org.drools.reliability.core; + +import org.drools.core.common.InternalFactHandle; +import org.drools.core.common.Storage; + +import java.lang.reflect.Field; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +public class SimpleSerializationReliableRefObjectStore extends SimpleSerializationReliableObjectStore { + + public SimpleSerializationReliableRefObjectStore(Storage storage) { + super(storage); + this.storage = storage.size()>0 ? updateObjectReferences(storage) : storage; + } + + private Storage updateObjectReferences(Storage storage){ + Storage updateStorage = storage; + + for (Long key: storage.keySet()){ + updateStorage.put(key, ((SerializableStoredRefObject) storage.get(key)).updateReferencedObjects(storage)); + } + return updateStorage; + } + + @Override + public void putIntoPersistedStorage(InternalFactHandle handle, boolean propagated) { + Object object = handle.getObject(); + StoredObject storedObject = factHandleToStoredObject(handle, reInitPropagated || propagated, object); + storage.put(getHandleForObject(object).getId(), setReferencedObjects(storedObject)); + } + + @Override + protected StoredObject createStoredObject(boolean propagated, Object object) { + return new SerializableStoredRefObject(object, propagated); + } + + private void updateReferencedObjects(StoredObject object){ + List referencedObjects = getReferencedObjects(object.getObject()); + if (referencedObjects.size()>0) { + + } + } + + private StoredObject setReferencedObjects(StoredObject object){ + List referencedObjects = getReferencedObjects(object.getObject()); + if (referencedObjects.size()>0) { + // for each referenced object in sObject + // lookup in storage, find the object of reference, get its fact handle id + // save this association in the StoredObject + referencedObjects.forEach(field -> { + field.setAccessible(true); + Object fieldObject = null; + try { + fieldObject = field.get(object.getObject()); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + Long objectKey = fromObjectToFactHandleId(fieldObject); + if (objectKey!=null){ + ((SerializableStoredRefObject) object).addReferencedObject(field.getName(), objectKey);} + }); + } + return object; + } + + private Long fromObjectToFactHandleId(Object object){ + for (Long key : this.storage.keySet()){ + if (( (SerializableStoredRefObject) storage.get(key)).getObject()==object){ + return key; + } + } + return null; + } + + private List getReferencedObjects(Object object){ + Field[] fields = object.getClass().getDeclaredFields(); + + List nonPrimitiveFields = Arrays.stream(fields) + .filter(field -> !field.getType().isPrimitive()) + .filter(field -> !field.getType().equals(String.class)) + .collect(Collectors.toList()); + return nonPrimitiveFields; + } +} diff --git a/drools-reliability/drools-reliability-infinispan/src/main/java/org/drools/reliability/infinispan/SimpleInfinispanReliableObjectStoreFactory.java b/drools-reliability/drools-reliability-infinispan/src/main/java/org/drools/reliability/infinispan/SimpleInfinispanReliableObjectStoreFactory.java index 5a28d66e6db..49ae4f3be96 100644 --- a/drools-reliability/drools-reliability-infinispan/src/main/java/org/drools/reliability/infinispan/SimpleInfinispanReliableObjectStoreFactory.java +++ b/drools-reliability/drools-reliability-infinispan/src/main/java/org/drools/reliability/infinispan/SimpleInfinispanReliableObjectStoreFactory.java @@ -19,9 +19,11 @@ import org.drools.reliability.core.SimpleReliableObjectStore; import org.drools.reliability.core.SimpleReliableObjectStoreFactory; import org.drools.reliability.core.SimpleSerializationReliableObjectStore; +import org.drools.reliability.core.SimpleSerializationReliableRefObjectStore; import org.drools.reliability.core.StorageManagerFactory; import org.drools.reliability.core.StoredObject; import org.drools.reliability.infinispan.proto.SimpleProtoStreamReliableObjectStore; +import org.kie.api.runtime.conf.PersistedSessionOption; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -31,13 +33,18 @@ public class SimpleInfinispanReliableObjectStoreFactory implements SimpleReliabl private static final Logger LOG = LoggerFactory.getLogger(SimpleInfinispanReliableObjectStoreFactory.class); - public SimpleReliableObjectStore createSimpleReliableObjectStore(Storage storage) { + public SimpleReliableObjectStore createSimpleReliableObjectStore(Storage storage, PersistedSessionOption persistedSessionOption) { if (((InfinispanStorageManager)StorageManagerFactory.get().getStorageManager()).isProtoStream()) { LOG.debug("Using SimpleProtoStreamReliableObjectStore"); return new SimpleProtoStreamReliableObjectStore(storage); } else { - LOG.debug("Using SimpleSerializationReliableObjectStore"); - return new SimpleSerializationReliableObjectStore(storage); + if (persistedSessionOption.getPersistenceObjectsStrategy()== PersistedSessionOption.PersistenceObjectsStrategy.OBJECT_REFERENCES){ + LOG.debug("Using SimpleSerializationReliableRefObjectStore"); + return new SimpleSerializationReliableRefObjectStore(storage); + }else{ + LOG.debug("Using SimpleSerializationReliableObjectStore"); + return new SimpleSerializationReliableObjectStore(storage); + } } } @@ -45,4 +52,5 @@ public SimpleReliableObjectStore createSimpleReliableObjectStore(Storage