mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-09-18 11:49:09 +00:00
bug5032: using the JoinedClassloader in the DataMiningService for function de-serialization
This commit is contained in:
+1
-8
@@ -21,7 +21,6 @@ import org.osgi.util.tracker.ServiceTracker;
|
||||
import com.sap.sailing.server.interfaces.RacingEventService;
|
||||
import com.sap.sse.common.settings.SerializableSettings;
|
||||
import com.sap.sse.datamining.DataMiningServer;
|
||||
import com.sap.sse.datamining.ModifiableDataMiningServer;
|
||||
import com.sap.sse.datamining.Query;
|
||||
import com.sap.sse.datamining.StatisticQueryDefinition;
|
||||
import com.sap.sse.datamining.components.AggregationProcessorDefinition;
|
||||
@@ -33,7 +32,6 @@ import com.sap.sse.datamining.functions.Function;
|
||||
import com.sap.sse.datamining.impl.components.DataRetrieverLevel;
|
||||
import com.sap.sse.datamining.impl.components.management.ReducedDimensions;
|
||||
import com.sap.sse.datamining.impl.data.QueryResultImpl;
|
||||
import com.sap.sse.datamining.shared.DataMiningQuerySerializer;
|
||||
import com.sap.sse.datamining.shared.DataMiningSession;
|
||||
import com.sap.sse.datamining.shared.GroupKey;
|
||||
import com.sap.sse.datamining.shared.SerializationDummy;
|
||||
@@ -59,19 +57,15 @@ public class DataMiningServiceImpl extends ProxiedRemoteServiceServlet implement
|
||||
private static final long serialVersionUID = -7951930891674894528L;
|
||||
|
||||
private final BundleContext context;
|
||||
|
||||
private final ServiceTracker<DataMiningServer, DataMiningServer> dataMiningServerTracker;
|
||||
private final ServiceTracker<SecurityService, SecurityService> securityServiceTracker;
|
||||
|
||||
private final StoredDataMiningQueryPersister storedDataMiningQueryPersistor;
|
||||
|
||||
private final DataMiningDTOFactory dtoFactory;
|
||||
|
||||
public DataMiningServiceImpl() {
|
||||
context = Activator.getDefault();
|
||||
dataMiningServerTracker = createAndOpenDataMiningServerTracker(context);
|
||||
securityServiceTracker = ServiceTrackerFactory.createAndOpen(context, SecurityService.class);
|
||||
|
||||
storedDataMiningQueryPersistor = new StoredDataMiningQueryPersisterImpl(getSecurityService(),
|
||||
dataMiningServerTracker);
|
||||
dtoFactory = new DataMiningDTOFactory();
|
||||
@@ -439,7 +433,6 @@ public class DataMiningServiceImpl extends ProxiedRemoteServiceServlet implement
|
||||
|
||||
@Override
|
||||
public ModifiableStatisticQueryDefinitionDTO getDeserializedQuery(String serializedQuery) {
|
||||
return (ModifiableStatisticQueryDefinitionDTO) DataMiningQuerySerializer.fromBase64String(serializedQuery,
|
||||
((ModifiableDataMiningServer) dataMiningServerTracker.getService()).getJoinedClassLoader());
|
||||
return (ModifiableStatisticQueryDefinitionDTO) dataMiningServerTracker.getService().fromBase64String(serializedQuery);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-3
@@ -13,7 +13,6 @@ import com.sap.sailing.server.impl.preferences.model.StoredDataMiningQueryPrefer
|
||||
import com.sap.sailing.server.impl.preferences.model.StoredDataMiningQueryPreferences;
|
||||
import com.sap.sse.common.Util;
|
||||
import com.sap.sse.datamining.DataMiningServer;
|
||||
import com.sap.sse.datamining.ModifiableDataMiningServer;
|
||||
import com.sap.sse.datamining.shared.DataMiningQuerySerializer;
|
||||
import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO;
|
||||
import com.sap.sse.datamining.shared.dto.StoredDataMiningQueryDTO;
|
||||
@@ -114,8 +113,7 @@ public class StoredDataMiningQueryPersisterImpl implements StoredDataMiningQuery
|
||||
|
||||
/** Converts a {@link StoredDataMiningQueryPreference} to a {@link StoredDataMiningQueryDTO}. */
|
||||
private StoredDataMiningQueryDTO transform(StoredDataMiningQueryPreference pref) {
|
||||
StatisticQueryDefinitionDTO query = DataMiningQuerySerializer.fromBase64String(pref.getSerializedQuery(),
|
||||
((ModifiableDataMiningServer) dataMiningServerTracker.getService()).getJoinedClassLoader());
|
||||
StatisticQueryDefinitionDTO query = dataMiningServerTracker.getService().fromBase64String(pref.getSerializedQuery());
|
||||
return new StoredDataMiningQueryDTOImpl(pref.getName(), pref.getId(), query);
|
||||
}
|
||||
|
||||
|
||||
@@ -13,5 +13,6 @@ Export-Package: com.sap.sse.datamining.shared,
|
||||
com.sap.sse.datamining.shared.util
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Require-Bundle: com.sap.sse.datamining.annotations,
|
||||
com.sap.sse.common
|
||||
com.sap.sse.common,
|
||||
com.sap.sse.shared.android
|
||||
Automatic-Module-Name: com.sap.sse.datamining.shared
|
||||
|
||||
-36
@@ -1,11 +1,8 @@
|
||||
package com.sap.sse.datamining.shared;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.ObjectStreamClass;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sse.common.Base64Utils;
|
||||
@@ -30,37 +27,4 @@ public final class DataMiningQuerySerializer {
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/** @return the {@link StatisticQueryDefinitionDTO} from a base 64 string deserialized with java serialization */
|
||||
public static StatisticQueryDefinitionDTO fromBase64String(final String string, ClassLoader joinedClassLoader) {
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = Base64Utils.fromBase64(string);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try (ByteArrayInputStream stream = new ByteArrayInputStream(bytes)) {
|
||||
ObjectInputStream in = new ObjectInputStream(stream) {
|
||||
@Override
|
||||
protected Class<?> resolveClass(ObjectStreamClass desc) throws IOException, ClassNotFoundException {
|
||||
if (joinedClassLoader != null) {
|
||||
try {
|
||||
return joinedClassLoader.loadClass(desc.getName());
|
||||
} catch (ClassNotFoundException e) {
|
||||
return super.resolveClass(desc);
|
||||
}
|
||||
}
|
||||
return super.resolveClass(desc);
|
||||
}
|
||||
};
|
||||
Object o = in.readObject();
|
||||
if (o instanceof StatisticQueryDefinitionDTO) {
|
||||
return (StatisticQueryDefinitionDTO) o;
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
LOG.severe("Could not load query: " + e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -4,17 +4,15 @@ import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.sap.sailing.datamining.SailingPredefinedQueries;
|
||||
import com.sap.sse.datamining.impl.DataMiningServerImpl;
|
||||
import com.sap.sse.datamining.shared.DataMiningQuerySerializer;
|
||||
import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO;
|
||||
|
||||
public class DataMiningQuerySerializerTest {
|
||||
|
||||
@Test
|
||||
public void testSerializationAndDeserialization() {
|
||||
|
||||
// test null
|
||||
testSerializationAndDeserialization(null);
|
||||
|
||||
// test all predefined queries
|
||||
for (StatisticQueryDefinitionDTO query : new SailingPredefinedQueries().getQueries().values()) {
|
||||
testSerializationAndDeserialization(query);
|
||||
@@ -23,7 +21,10 @@ public class DataMiningQuerySerializerTest {
|
||||
|
||||
private void testSerializationAndDeserialization(final StatisticQueryDefinitionDTO dto) {
|
||||
String base64 = DataMiningQuerySerializer.toBase64String(dto);
|
||||
StatisticQueryDefinitionDTO deserialized = DataMiningQuerySerializer.fromBase64String(base64, null);
|
||||
StatisticQueryDefinitionDTO deserialized = new DataMiningServerImpl(
|
||||
/* executorService */ null, /* functionRegistry */ null, /* dataSourceProviderRegistry */ null,
|
||||
/* dataRetrieverChainDefinitionRegistry */ null, /* aggregationProcessorDefinitionRegistry */ null,
|
||||
/* queryDefinitionRegistry */ null).fromBase64String(base64);
|
||||
Assert.assertEquals(dto, deserialized);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.sap.sse.datamining.shared.impl.dto.DataRetrieverChainDefinitionDTO;
|
||||
import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
|
||||
import com.sap.sse.datamining.shared.impl.dto.ModifiableStatisticQueryDefinitionDTO;
|
||||
import com.sap.sse.i18n.ResourceBundleStringMessages;
|
||||
import com.sap.sse.util.JoinedClassLoader;
|
||||
|
||||
|
||||
public interface DataMiningServer {
|
||||
@@ -52,6 +53,8 @@ public interface DataMiningServer {
|
||||
<DataSourceType, ResultType> Query<ResultType> createQuery(StatisticQueryDefinition<DataSourceType, ?, ?, ResultType> queryDefinition);
|
||||
<ResultType> QueryResult<ResultType> runNewQueryAndAbortPreviousQueries(DataMiningSession session, Query<ResultType> query);
|
||||
int getNumberOfRunningQueries();
|
||||
JoinedClassLoader getJoinedClassLoader();
|
||||
StatisticQueryDefinitionDTO fromBase64String(String string);
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------------
|
||||
// Component Accessors as default methods
|
||||
@@ -128,5 +131,4 @@ public interface DataMiningServer {
|
||||
default ModifiableStatisticQueryDefinitionDTO getPredefinedQueryDefinitionDTO(PredefinedQueryIdentifier identifier) {
|
||||
return getQueryDefinitionDTOProvider().get(identifier);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,13 +9,11 @@ import com.sap.sse.datamining.components.management.QueryDefinitionDTORegistry;
|
||||
import com.sap.sse.datamining.shared.dto.StatisticQueryDefinitionDTO;
|
||||
import com.sap.sse.datamining.shared.impl.PredefinedQueryIdentifier;
|
||||
import com.sap.sse.i18n.ResourceBundleStringMessages;
|
||||
import com.sap.sse.util.JoinedClassLoader;
|
||||
|
||||
public interface ModifiableDataMiningServer extends DataMiningServer {
|
||||
|
||||
void addDataMiningBundleClassLoader(ClassLoader classLoader);
|
||||
void removeDataMiningBundleClassLoader(ClassLoader classLoader);
|
||||
JoinedClassLoader getJoinedClassLoader();
|
||||
|
||||
void addStringMessages(ResourceBundleStringMessages stringMessages);
|
||||
void removeStringMessages(ResourceBundleStringMessages stringMessages);
|
||||
|
||||
+38
-1
@@ -1,5 +1,8 @@
|
||||
package com.sap.sse.datamining.impl;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -12,7 +15,10 @@ import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.sap.sse.common.Base64Utils;
|
||||
import com.sap.sse.common.settings.SerializableSettings;
|
||||
import com.sap.sse.datamining.DataSourceProvider;
|
||||
import com.sap.sse.datamining.ModifiableDataMiningServer;
|
||||
@@ -50,8 +56,10 @@ import com.sap.sse.datamining.shared.impl.dto.FunctionDTO;
|
||||
import com.sap.sse.i18n.ResourceBundleStringMessages;
|
||||
import com.sap.sse.i18n.impl.CompoundResourceBundleStringMessages;
|
||||
import com.sap.sse.util.JoinedClassLoader;
|
||||
import com.sap.sse.util.ObjectInputStreamResolvingAgainstCache;
|
||||
|
||||
public class DataMiningServerImpl implements ModifiableDataMiningServer {
|
||||
private static final Logger logger = Logger.getLogger(DataMiningServerImpl.class.getName());
|
||||
|
||||
private static final long MEMORY_CHECK_PERIOD = 5;
|
||||
private static final TimeUnit MEMORY_CHECK_PERIOD_UNIT = TimeUnit.SECONDS;
|
||||
@@ -90,7 +98,6 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
|
||||
this.dataSourceProviderRegistry = dataSourceProviderRegistry;
|
||||
this.dataRetrieverChainDefinitionRegistry = dataRetrieverChainDefinitionRegistry;
|
||||
this.aggregationProcessorDefinitionRegistry = aggregationProcessorDefinitionRegistry;
|
||||
|
||||
this.queryDefinitionRegistry = queryDefinitionRegistry;
|
||||
}
|
||||
|
||||
@@ -143,6 +150,36 @@ public class DataMiningServerImpl implements ModifiableDataMiningServer {
|
||||
return new JoinedClassLoader(dataMiningClassLoaders);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the {@link StatisticQueryDefinitionDTO} from a base 64 string deserialized with java serialization,
|
||||
* considering the {@link #getJoinedClassLoader() joined class loader} that offers all classes of all
|
||||
* bundles that currently provide data mining components to this server
|
||||
*/
|
||||
@Override
|
||||
public StatisticQueryDefinitionDTO fromBase64String(final String string) {
|
||||
byte[] bytes;
|
||||
try {
|
||||
bytes = Base64Utils.fromBase64(string);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return null;
|
||||
}
|
||||
final ClassLoader oldThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(getJoinedClassLoader());
|
||||
try (final ObjectInputStream in = new ObjectInputStreamResolvingAgainstCache<Object>(
|
||||
new ByteArrayInputStream(bytes), /* dummy "cache" */ new Object(), /* resolve listener */ null) {}) {
|
||||
Object o = in.readObject();
|
||||
if (o instanceof StatisticQueryDefinitionDTO) {
|
||||
return (StatisticQueryDefinitionDTO) o;
|
||||
}
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
logger.log(Level.SEVERE, "Could not load query", e);
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(oldThreadContextClassLoader);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addDataMiningBundleClassLoader(ClassLoader classLoader) {
|
||||
dataMiningClassLoaders.add(classLoader);
|
||||
|
||||
Reference in New Issue
Block a user