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 2021/01/21 13:38:41 UTC

[isis] branch master updated: ISIS-2480: adds schema creation support (JPA)

This is an automated email from the ASF dual-hosted git repository.

ahuber pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/isis.git


The following commit(s) were added to refs/heads/master by this push:
     new 229a1f2  ISIS-2480: adds schema creation support (JPA)
229a1f2 is described below

commit 229a1f2b912ab0ef30acf6b0c31c65a95c8ca79a
Author: Andi Huber <ah...@apache.org>
AuthorDate: Thu Jan 21 14:38:24 2021 +0100

    ISIS-2480: adds schema creation support (JPA)
---
 .../apache/isis/core/config/IsisConfiguration.java | 39 ++++++++++++-
 .../src/main/resources/META-INF/orm-secman.xml     | 44 +++++++++++++++
 .../jpa/eclipselink/IsisModuleJpaEclipselink.java  | 66 +++++++++++++++++++++-
 3 files changed, 144 insertions(+), 5 deletions(-)

diff --git a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
index d2b65f6..2f20e2b 100644
--- a/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
+++ b/core/config/src/main/java/org/apache/isis/core/config/IsisConfiguration.java
@@ -1874,10 +1874,45 @@ public class IsisConfiguration {
                 }
             }
         }
+        
+        private final Jpa jpa = new Jpa();
+        @Data
+        public static class Jpa {
+            
+            /**
+             * List of additional schemas to be auto-created.
+             * <p>
+             * Explicitly creates given list of schemas by using the specified 
+             * {@link #getCreateSchemaSqlTemplate()} to generate the actual SQL 
+             * statement against the configured data-source.
+             * <p> 
+             * This configuration mechanism does not consider any schema-auto-creation 
+             * configuration (if any), that independently is provided the standard JPA way.
+             */
+            private final List<String> autoCreateSchemas = new ArrayList<>();
+            
+            /**
+             * Does lookup additional "mapping-files" in META-INF/orm-<i>name</i>.xml
+             * (equivalent to "mapping-file" entries in persistence.xml) and adds these 
+             * to those that are already configured the <i>Spring Data</i> way (if any). 
+             */
+            private final List<String> additionalOrmFiles = new ArrayList<>();
+            
+            /**
+             * SQL syntax to create a DB schema.
+             * <p>
+             * This template is passed through {@link String#format(String, schemaName)} to 
+             * make the actual SQL statement thats to be used against the configured data-source.
+             * <p>
+             * Default template is {@literal CREATE SCHEMA IF NOT EXISTS %S} with the schema name 
+             * converted to upper-case.  
+             */
+            private String createSchemaSqlTemplate = "CREATE SCHEMA IF NOT EXISTS %S";
+        
+        }
     }
 
 
-
     private final Viewer viewer = new Viewer();
     @Data
     public static class Viewer {
@@ -2959,7 +2994,7 @@ public class IsisConfiguration {
         }
     }
 
-
+    
     private final Extensions extensions = new Extensions();
     @Data
     public static class Extensions {
diff --git a/extensions/security/secman/persistence-jpa/src/main/resources/META-INF/orm-secman.xml b/extensions/security/secman/persistence-jpa/src/main/resources/META-INF/orm-secman.xml
new file mode 100644
index 0000000..b2f9e6a
--- /dev/null
+++ b/extensions/security/secman/persistence-jpa/src/main/resources/META-INF/orm-secman.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+<entity-mappings xmlns="http://xmlns.jcp.org/xml/ns/persistence/orm"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence/orm
+      http://xmlns.jcp.org/xml/ns/persistence/orm_2_1.xsd"
+    version="2.1">
+
+	<package>org.apache.isis.extensions.secman.jpa.dom</package>
+	
+	<entity class="permission.ApplicationPermission">
+		<table schema="secman"/>
+	</entity>
+	
+	<entity class="role.ApplicationRole">
+		<table schema="secman"/>
+	</entity>
+	
+	<entity class="tenancy.ApplicationTenancy">
+		<table schema="secman"/>
+	</entity>
+	
+	<entity class="user.ApplicationUser">
+		<table schema="secman"/>
+	</entity>
+
+</entity-mappings>
\ No newline at end of file
diff --git a/persistence/jpa/eclipselink/src/main/java/org/apache/isis/persistence/jpa/eclipselink/IsisModuleJpaEclipselink.java b/persistence/jpa/eclipselink/src/main/java/org/apache/isis/persistence/jpa/eclipselink/IsisModuleJpaEclipselink.java
index d2b3d20..0d5e3c6 100644
--- a/persistence/jpa/eclipselink/src/main/java/org/apache/isis/persistence/jpa/eclipselink/IsisModuleJpaEclipselink.java
+++ b/persistence/jpa/eclipselink/src/main/java/org/apache/isis/persistence/jpa/eclipselink/IsisModuleJpaEclipselink.java
@@ -36,28 +36,41 @@ import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
 import org.springframework.transaction.jta.JtaTransactionManager;
 
 import org.apache.isis.applib.services.inject.ServiceInjector;
+import org.apache.isis.core.config.IsisConfiguration;
 import org.apache.isis.persistence.jpa.eclipselink.inject.BeanManagerForEntityListeners;
 import org.apache.isis.persistence.jpa.integration.IsisModuleJpaIntegration;
 
+import lombok.SneakyThrows;
+import lombok.val;
+import lombok.extern.log4j.Log4j2;
+
 /**
  * EclipseLink integration. 
+ * <p>
  * Sets up EclipseLink as the implementation provider for Spring Data JPA.
  * 
+ * @implNote does not (yet) support weaving, explicitly disables it
  * @see <a href="https://www.baeldung.com/spring-eclipselink">baeldung.com</a>
  */
 @Configuration 
 @Import({
     IsisModuleJpaIntegration.class
 })
+@Log4j2
 public class IsisModuleJpaEclipselink extends JpaBaseConfiguration { 
 
     @Inject private Provider<ServiceInjector> serviceInjectorProvider;
     
     protected IsisModuleJpaEclipselink(
+            IsisConfiguration isisConfiguration,
             DataSource dataSource, 
             JpaProperties properties,
             ObjectProvider<JtaTransactionManager> jtaTransactionManager) {
-        super(dataSource, properties, jtaTransactionManager);
+        
+        super(
+                autoCreateSchemas(dataSource, isisConfiguration), 
+                addAdditionalOrmFiles(properties, isisConfiguration), 
+                jtaTransactionManager);
     }
 
     @Override 
@@ -65,15 +78,62 @@ public class IsisModuleJpaEclipselink extends JpaBaseConfiguration {
         return new EclipseLinkJpaVendorAdapter(); 
     }
 
-    //TODO[2033] partly application specific configuration that belongs to application.yaml
     @Override
     protected Map<String, Object> getVendorProperties() {
         HashMap<String, Object> jpaProps = new HashMap<>();
         jpaProps.put(PersistenceUnitProperties.WEAVING, "false");
-        jpaProps.put(PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_DATABASE_SCHEMAS, "true");
+//        jpaProps.put(PersistenceUnitProperties.SCHEMA_GENERATION_CREATE_DATABASE_SCHEMAS, "true");
         jpaProps.put(PersistenceUnitProperties.DDL_GENERATION, PersistenceUnitProperties.CREATE_OR_EXTEND);
         jpaProps.put(PersistenceUnitProperties.CDI_BEANMANAGER, new BeanManagerForEntityListeners(serviceInjectorProvider));
         return jpaProps;
     }
 
+    /**
+     * integrates with settings from isis.persistence.jpa.*
+     */
+    @SneakyThrows
+    protected static DataSource autoCreateSchemas(
+            final DataSource dataSource,
+            final IsisConfiguration isisConfiguration) {
+        
+        val isisJpaConf = isisConfiguration.getPersistence().getJpa();
+        
+        if(!isisJpaConf.getAutoCreateSchemas().isEmpty()) {
+            
+            log.info("about to create db schema(s) {}", isisJpaConf.getAutoCreateSchemas());
+            
+            try(val con = dataSource.getConnection()){
+                
+                val s = con.createStatement();
+                
+                for(val schema : isisJpaConf.getAutoCreateSchemas()) {
+                    s.execute(String.format(isisJpaConf.getCreateSchemaSqlTemplate(), schema));
+                }
+                
+            }
+        }
+
+        return dataSource;
+    }
+    
+    /**
+     * integrates with settings from isis.persistence.jpa.*
+     */
+    protected static JpaProperties addAdditionalOrmFiles(
+            JpaProperties properties,
+            IsisConfiguration isisConfiguration) {
+
+        val isisJpaConf = isisConfiguration.getPersistence().getJpa();
+        
+        isisJpaConf.getAdditionalOrmFiles()
+        .forEach(schema->properties.getMappingResources()
+                .add(String.format("META-INF/orm-%s.xml", schema)));
+        
+        if(!properties.getMappingResources().isEmpty()) {
+            log.info("using mapping-resources {}", properties.getMappingResources());
+        }
+        
+        return properties;
+    }
+    
 }
\ No newline at end of file