View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.syncope.core.persistence.jpa;
20  
21  import com.zaxxer.hikari.HikariConfig;
22  import com.zaxxer.hikari.HikariDataSource;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.Map;
26  import java.util.Objects;
27  import javax.sql.DataSource;
28  import org.apache.syncope.common.lib.SyncopeConstants;
29  import org.apache.syncope.core.persistence.jpa.openjpa.ConnectorManagerRemoteCommitListener;
30  import org.apache.syncope.core.persistence.jpa.spring.CommonEntityManagerFactoryConf;
31  import org.apache.syncope.core.persistence.jpa.spring.DomainEntityManagerFactoryBean;
32  import org.springframework.beans.factory.annotation.Qualifier;
33  import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
34  import org.springframework.boot.context.properties.EnableConfigurationProperties;
35  import org.springframework.context.annotation.Bean;
36  import org.springframework.context.annotation.Configuration;
37  import org.springframework.context.annotation.DependsOn;
38  import org.springframework.core.io.ClassPathResource;
39  import org.springframework.core.io.ResourceLoader;
40  import org.springframework.jdbc.datasource.init.DataSourceInitializer;
41  import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
42  import org.springframework.jndi.JndiObjectFactoryBean;
43  import org.springframework.orm.jpa.JpaTransactionManager;
44  import org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter;
45  import org.springframework.transaction.PlatformTransactionManager;
46  import org.springframework.transaction.support.TransactionTemplate;
47  
48  @EnableConfigurationProperties(PersistenceProperties.class)
49  @Configuration(proxyBeanMethods = false)
50  public class MasterDomain {
51  
52      @ConditionalOnMissingBean(name = "MasterDataSource")
53      @Bean(name = "MasterDataSource")
54      public JndiObjectFactoryBean masterDataSource(final PersistenceProperties props) {
55          HikariConfig hikariConfig = new HikariConfig();
56          hikariConfig.setDriverClassName(props.getDomain().get(0).getJdbcDriver());
57          hikariConfig.setJdbcUrl(props.getDomain().get(0).getJdbcURL());
58          hikariConfig.setUsername(props.getDomain().get(0).getDbUsername());
59          hikariConfig.setPassword(props.getDomain().get(0).getDbPassword());
60          hikariConfig.setTransactionIsolation(props.getDomain().get(0).getTransactionIsolation().name());
61          hikariConfig.setMaximumPoolSize(props.getDomain().get(0).getPoolMaxActive());
62          hikariConfig.setMinimumIdle(props.getDomain().get(0).getPoolMinIdle());
63  
64          JndiObjectFactoryBean masterDataSource = new JndiObjectFactoryBean();
65          masterDataSource.setJndiName("java:comp/env/jdbc/syncopeMasterDataSource");
66          masterDataSource.setDefaultObject(new HikariDataSource(hikariConfig));
67          return masterDataSource;
68      }
69  
70      @ConditionalOnMissingBean(name = "MasterDataSourceInitializer")
71      @Bean(name = "MasterDataSourceInitializer")
72      public DataSourceInitializer masterDataSourceInitializer(
73              final PersistenceProperties props,
74              @Qualifier("MasterDataSource")
75              final JndiObjectFactoryBean masterDataSource) {
76  
77          ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
78          databasePopulator.setContinueOnError(true);
79          databasePopulator.setIgnoreFailedDrops(true);
80          databasePopulator.setSqlScriptEncoding("UTF-8");
81          databasePopulator.addScript(new ClassPathResource("/audit/" + props.getDomain().get(0).getAuditSql()));
82  
83          DataSourceInitializer dataSourceInitializer = new DataSourceInitializer();
84          dataSourceInitializer.setDataSource((DataSource) Objects.requireNonNull(masterDataSource.getObject()));
85          dataSourceInitializer.setEnabled(true);
86          dataSourceInitializer.setDatabasePopulator(databasePopulator);
87          return dataSourceInitializer;
88      }
89  
90      @ConditionalOnMissingBean(name = "MasterEntityManagerFactory")
91      @DependsOn("commonEMFConf")
92      @Bean(name = "MasterEntityManagerFactory")
93      public DomainEntityManagerFactoryBean masterEntityManagerFactory(
94              final PersistenceProperties props,
95              @Qualifier("MasterDataSource")
96              final JndiObjectFactoryBean masterDataSource,
97              final CommonEntityManagerFactoryConf commonEMFConf) {
98  
99          OpenJpaVendorAdapter vendorAdapter = new OpenJpaVendorAdapter();
100         vendorAdapter.setShowSql(false);
101         vendorAdapter.setGenerateDdl(true);
102         vendorAdapter.setDatabasePlatform(props.getDomain().get(0).getDatabasePlatform());
103 
104         DomainEntityManagerFactoryBean masterEntityManagerFactory = new DomainEntityManagerFactoryBean();
105         masterEntityManagerFactory.setMappingResources(props.getDomain().get(0).getOrm());
106         masterEntityManagerFactory.setPersistenceUnitName(SyncopeConstants.MASTER_DOMAIN);
107         masterEntityManagerFactory.setDataSource(Objects.requireNonNull((DataSource) masterDataSource.getObject()));
108         masterEntityManagerFactory.setJpaVendorAdapter(vendorAdapter);
109         masterEntityManagerFactory.setCommonEntityManagerFactoryConf(commonEMFConf);
110         masterEntityManagerFactory.setConnectorManagerRemoteCommitListener(
111                 new ConnectorManagerRemoteCommitListener(SyncopeConstants.MASTER_DOMAIN));
112 
113         if (props.getMetaDataFactory() != null) {
114             masterEntityManagerFactory.setJpaPropertyMap(Map.of(
115                     "openjpa.MetaDataFactory",
116                     props.getMetaDataFactory().replace("##orm##", props.getDomain().get(0).getOrm())));
117         }
118 
119         return masterEntityManagerFactory;
120     }
121 
122     @ConditionalOnMissingBean(name = "MasterTransactionManager")
123     @Bean(name = { "MasterTransactionManager", "Master" })
124     public PlatformTransactionManager transactionManager(
125             @Qualifier("MasterEntityManagerFactory")
126             final DomainEntityManagerFactoryBean masterEntityManagerFactory) {
127 
128         return new JpaTransactionManager(Objects.requireNonNull(masterEntityManagerFactory.getObject()));
129     }
130 
131     @ConditionalOnMissingBean(name = "MasterTransactionTemplate")
132     @Bean(name = "MasterTransactionTemplate")
133     public TransactionTemplate transactionTemplate(
134             @Qualifier("MasterTransactionManager")
135             final PlatformTransactionManager masterTransactionManager) {
136 
137         return new TransactionTemplate(masterTransactionManager);
138     }
139 
140     @Bean(name = "MasterContentXML")
141     public InputStream masterContentXML(
142             final ResourceLoader resourceLoader,
143             final PersistenceProperties props) throws IOException {
144 
145         return resourceLoader.getResource(props.getDomain().get(0).getContent()).getInputStream();
146     }
147 
148     @Bean(name = "MasterKeymasterConfParamsJSON")
149     public InputStream masterKeymasterConfParamsJSON(
150             final ResourceLoader resourceLoader,
151             final PersistenceProperties props) throws IOException {
152 
153         return resourceLoader.getResource(props.getDomain().get(0).getKeymasterConfParams()).getInputStream();
154     }
155 
156     @Bean(name = "MasterDatabaseSchema")
157     public String masterDatabaseSchema(final PersistenceProperties props) {
158         return props.getDomain().get(0).getDbSchema();
159     }
160 }