You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by ah...@apache.org on 2018/11/09 08:01:23 UTC
[isis] branch v2 updated: ISIS-2020: properly predict Federated
Store Manager
This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch v2
in repository https://gitbox.apache.org/repos/asf/isis.git
The following commit(s) were added to refs/heads/v2 by this push:
new 44d3079 ISIS-2020: properly predict Federated Store Manager
44d3079 is described below
commit 44d30790eb139bf8f0394d5fbe7f23decbdf3f46
Author: Andi Huber <ah...@apache.org>
AuthorDate: Fri Nov 9 08:49:19 2018 +0100
ISIS-2020: properly predict Federated Store Manager
Task-Url: https://issues.apache.org/jira/browse/ISIS-2020
---
.../org/apache/isis/applib/util/JaxbAdapters.java | 7 ++
.../system/persistence/DNStoreManagerType.java | 130 +++++++++++++++++++++
.../DataNucleusApplicationComponents5.java | 85 ++++++--------
3 files changed, 173 insertions(+), 49 deletions(-)
diff --git a/core/applib/src/main/java/org/apache/isis/applib/util/JaxbAdapters.java b/core/applib/src/main/java/org/apache/isis/applib/util/JaxbAdapters.java
index dcbe8a6..ace6f9c 100644
--- a/core/applib/src/main/java/org/apache/isis/applib/util/JaxbAdapters.java
+++ b/core/applib/src/main/java/org/apache/isis/applib/util/JaxbAdapters.java
@@ -27,7 +27,14 @@ import javax.xml.bind.annotation.adapters.XmlAdapter;
/**
* Provides JAXB XmlAdapters for Java built-in temporal types.
* Others types might be added, if convenient.
+ * <p>
*
+ * Example:<pre>
+ * @XmlElement @XmlJavaTypeAdapter(JaxbAdapters.LocalDateAdapter.class)
+ * @Getter @Setter private LocalDate javaLocalDate;
+ * </pre>
+ *
+ *
* @since 2.0.0-M2
*/
public final class JaxbAdapters {
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DNStoreManagerType.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DNStoreManagerType.java
new file mode 100644
index 0000000..71e7447
--- /dev/null
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DNStoreManagerType.java
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.isis.core.runtime.system.persistence;
+
+import java.util.Map;
+import java.util.function.Function;
+
+import org.datanucleus.PersistenceNucleusContext;
+import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
+import org.datanucleus.store.StoreManager;
+import org.datanucleus.store.federation.FederatedStoreManager;
+import org.datanucleus.store.schema.SchemaAwareStoreManager;
+
+/**
+ * Given only config properties, tries to find, which kind of store manager
+ * Datanucleus is going to utilize. We do this prior to bootstrapping Datanucleus,
+ * to allow for programmatic override of given config properties.
+ * (eg. proper schema creation setup)
+ *
+ * @since 2.0.0-M2
+ */
+enum DNStoreManagerType {
+
+ SchemaAware,
+ Federated, // [ahuber] not used by now
+ Other
+ ;
+
+ public static DNStoreManagerType typeOf(Map<String,String> datanucleusProps) {
+
+ if(hasSecondaryDataStore(datanucleusProps)) {
+ return Federated;
+ }
+
+ if(isKnownSchemaAwareStoreManagerIfNotFederated(datanucleusProps)) {
+ return SchemaAware;
+ }
+
+ return probe(datanucleusProps, storeManager->{
+
+ if(storeManager instanceof SchemaAwareStoreManager) {
+ return SchemaAware;
+ }
+
+ if(storeManager instanceof FederatedStoreManager) {
+ return Federated;
+ }
+
+ return Other;
+
+ });
+
+ }
+
+ public boolean isSchemaAware() {
+ return this == SchemaAware;
+ }
+
+ // -- HELPER
+
+ /* not necessarily complete, just for speed up */
+ private final static String[] knownSchemaAwareIfNotFederated = {
+ "jdbc:hsqldb:",
+ "jdbc:sqlserver:",
+ "jdbc:h2:",
+ "jdbc:mysql:",
+ "jdbc:mariadb:",
+ "jdbc:postgresql:",
+ "jdbc:db2:",
+ };
+
+ private static boolean hasSecondaryDataStore(Map<String,String> datanucleusProps) {
+ final boolean hasSecondaryDataStore = datanucleusProps.keySet().stream()
+ .anyMatch(key->key.startsWith("datanucleus.datastore."));
+ return hasSecondaryDataStore;
+ }
+
+ private static boolean isKnownSchemaAwareStoreManagerIfNotFederated(Map<String,String> datanucleusProps) {
+
+ // this saves some time, but also avoids the (still undiagnosed) issue that instantiating the
+ // PMF can cause the ClassMetadata for the entity classes to be loaded in and cached prior to
+ // registering the CreateSchemaObjectFromClassData (to invoke 'create schema' first)
+ final String connectionUrl = datanucleusProps.get("javax.jdo.option.ConnectionURL");
+ if(connectionUrl != null) {
+ for(String magic : knownSchemaAwareIfNotFederated) {
+ if (connectionUrl.startsWith(magic)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ private static DNStoreManagerType probe(
+ Map<String,String> datanucleusProps,
+ Function<StoreManager, DNStoreManagerType> categorizer) {
+
+ // we create a throw-away instance of PMF so that we can probe whether DN has
+ // been configured with a schema-aware store manager or not.
+ final JDOPersistenceManagerFactory probePmf = (JDOPersistenceManagerFactory)
+ DataNucleusApplicationComponents5.newPersistenceManagerFactory(datanucleusProps);
+
+ try {
+ final PersistenceNucleusContext nucleusContext = probePmf.getNucleusContext();
+ final StoreManager storeManager = nucleusContext.getStoreManager();
+
+ return categorizer.apply(storeManager);
+ } finally {
+ probePmf.close();
+ }
+ }
+
+}
diff --git a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
index 78b36b4..3fa3287 100644
--- a/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
+++ b/core/plugins/jdo-datanucleus-5/src/main/java/org/apache/isis/core/runtime/system/persistence/DataNucleusApplicationComponents5.java
@@ -18,8 +18,6 @@
*/
package org.apache.isis.core.runtime.system.persistence;
-import static org.apache.isis.commons.internal.base._NullSafe.stream;
-
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -33,7 +31,6 @@ import org.datanucleus.PropertyNames;
import org.datanucleus.api.jdo.JDOPersistenceManagerFactory;
import org.datanucleus.metadata.MetaDataListener;
import org.datanucleus.metadata.MetaDataManager;
-import org.datanucleus.store.StoreManager;
import org.datanucleus.store.schema.SchemaAwareStoreManager;
import org.apache.isis.commons.internal.collections._Maps;
@@ -49,6 +46,8 @@ import org.apache.isis.objectstore.jdo.datanucleus.DataNucleusPropertiesAware;
import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoNamedQuery;
import org.apache.isis.objectstore.jdo.metamodel.facets.object.query.JdoQueryFacet;
+import static org.apache.isis.commons.internal.base._NullSafe.stream;
+
public class DataNucleusApplicationComponents5 implements ApplicationScopedComponent {
public static final String CLASS_METADATA_LOADED_LISTENER_KEY = "classMetadataLoadedListener";
@@ -65,7 +64,8 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
*/
public static MetaDataManager getMetaDataManager() {
return instance != null
- ? ((JDOPersistenceManagerFactory)instance.persistenceManagerFactory).getNucleusContext().getMetaDataManager()
+ ? ((JDOPersistenceManagerFactory)instance.persistenceManagerFactory)
+ .getNucleusContext().getMetaDataManager()
: null;
}
@@ -97,7 +97,8 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
this.persistableClassNameSet = persistableClassNameSet;
this.jdoObjectstoreConfig = configuration;
- persistenceManagerFactory = createPmfAndSchemaIfRequired(this.persistableClassNameSet, this.datanucleusProps);
+ persistenceManagerFactory = createPmfAndSchemaIfRequired(
+ this.persistableClassNameSet, this.datanucleusProps);
// for JRebel plugin
instance = this;
@@ -117,60 +118,28 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
}
}
- private static PersistenceManagerFactory newPersistenceManagerFactory(Map<String, String> datanucleusProps) {
+ static PersistenceManagerFactory newPersistenceManagerFactory(Map<String, String> datanucleusProps) {
return JDOHelper.getPersistenceManagerFactory(datanucleusProps, IsisContext.getClassLoader());
}
- private static boolean isSchemaAwareStoreManager(Map<String,String> datanucleusProps) {
-
- // this saves some time, but also avoids the (still undiagnosed) issue that instantiating the
- // PMF can cause the ClassMetadata for the entity classes to be loaded in and cached prior to
- // registering the CreateSchemaObjectFromClassData (to invoke 'create schema' first)
- final String connectionUrl = datanucleusProps.get("javax.jdo.option.ConnectionURL");
- if(connectionUrl != null) {
- if (connectionUrl.startsWith("jdbc:hsqldb")) return true;
- if (connectionUrl.startsWith("jdbc:sqlserver")) return true;
- }
-
- // we create a throw-away instance of PMF so that we can probe whether DN has
- // been configured with a schema-aware store manager or not.
- final JDOPersistenceManagerFactory probePmf =
- (JDOPersistenceManagerFactory) newPersistenceManagerFactory(datanucleusProps);
-
-
- try {
- final PersistenceNucleusContext nucleusContext = probePmf.getNucleusContext();
- final StoreManager storeManager = nucleusContext.getStoreManager();
- return storeManager instanceof SchemaAwareStoreManager;
- } finally {
- probePmf.close();
- }
- }
-
// REF: http://www.datanucleus.org/products/datanucleus/jdo/schema.html
- private PersistenceManagerFactory createPmfAndSchemaIfRequired(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
+ private PersistenceManagerFactory createPmfAndSchemaIfRequired(
+ final Set<String> persistableClassNameSet,
+ final Map<String, String> datanucleusProps) {
+ final DNStoreManagerType dnStoreManagerType = DNStoreManagerType.typeOf(datanucleusProps);
+
PersistenceManagerFactory persistenceManagerFactory;
- if(isSchemaAwareStoreManager(datanucleusProps)) {
+
+ if(dnStoreManagerType.isSchemaAware()) {
// rather than reinvent too much of the wheel, we reuse the same property that DN would check
// for if it were doing the auto-creation itself (read from isis.properties)
final boolean createSchema = isSet(datanucleusProps, PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL);
if(createSchema) {
-
- // we *don't* use DN's eager loading (autoStart), because doing so means that it attempts to
- // create the table before the schema (for any entities annotated @PersistenceCapable(schema=...)
- //
- // instead, we manually create the schema ourselves
- // (if the configured StoreMgr supports it, and if requested in isis.properties)
- //
- datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "false"); // turn off, cos want to do the schema object ourselves...
- datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_DATABASE, "false");
- datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true"); // but have DN do everything else...
- datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
- datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
-
+
+ configureAutoCreateSchema(datanucleusProps);
persistenceManagerFactory = newPersistenceManagerFactory(datanucleusProps);
createSchema(persistenceManagerFactory, persistableClassNameSet, datanucleusProps);
@@ -191,7 +160,24 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
}
- private void configureAutoStart(final Set<String> persistableClassNameSet, final Map<String, String> datanucleusProps) {
+ private void configureAutoCreateSchema(final Map<String, String> datanucleusProps) {
+ // we *don't* use DN's eager loading (autoStart), because doing so means that it attempts to
+ // create the table before the schema (for any entities annotated @PersistenceCapable(schema=...)
+ //
+ // instead, we manually create the schema ourselves
+ // (if the configured StoreMgr supports it, and if requested in isis.properties)
+ //
+ datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_ALL, "false"); // turn off, cos want to do the schema object ourselves...
+ datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_DATABASE, "false");
+ datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_TABLES, "true"); // but have DN do everything else...
+ datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_COLUMNS, "true");
+ datanucleusProps.put(PropertyNames.PROPERTY_SCHEMA_AUTOCREATE_CONSTRAINTS, "true");
+ }
+
+ private void configureAutoStart(
+ final Set<String> persistableClassNameSet,
+ final Map<String, String> datanucleusProps) {
+
final String persistableClassNames =
stream(persistableClassNameSet).collect(Collectors.joining(","));
@@ -208,7 +194,8 @@ public class DataNucleusApplicationComponents5 implements ApplicationScopedCompo
JDOPersistenceManagerFactory jdopmf = (JDOPersistenceManagerFactory) persistenceManagerFactory;
final PersistenceNucleusContext nucleusContext = jdopmf.getNucleusContext();
- final SchemaAwareStoreManager schemaAwareStoreManager = (SchemaAwareStoreManager)nucleusContext.getStoreManager();
+ final SchemaAwareStoreManager schemaAwareStoreManager =
+ (SchemaAwareStoreManager)nucleusContext.getStoreManager();
final MetaDataManager metaDataManager = nucleusContext.getMetaDataManager();