View Javadoc
1   /*
2    *    Copyright 2009-2022 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.mybatis.guice.datasource.builtin;
17  
18  import static org.junit.jupiter.api.Assertions.assertEquals;
19  import static org.junit.jupiter.api.Assertions.assertNotEquals;
20  import static org.mockito.Mockito.mock;
21  import static org.mockito.Mockito.verify;
22  
23  import com.google.inject.AbstractModule;
24  import com.google.inject.Guice;
25  import com.google.inject.Injector;
26  import com.google.inject.name.Names;
27  
28  import java.sql.SQLException;
29  import java.util.Hashtable;
30  
31  import javax.naming.Context;
32  import javax.naming.InitialContext;
33  import javax.naming.NamingException;
34  import javax.naming.spi.InitialContextFactory;
35  import javax.sql.DataSource;
36  
37  import org.apache.naming.java.javaURLContextFactory;
38  import org.junit.jupiter.api.BeforeAll;
39  import org.junit.jupiter.api.Test;
40  import org.junit.jupiter.api.extension.ExtendWith;
41  import org.mockito.junit.jupiter.MockitoExtension;
42  
43  @ExtendWith(MockitoExtension.class)
44  class JndiDataSourceProviderTest {
45    private static String dataSourceName;
46    private static String contextName;
47    private static DataSource globalDataSource;
48    private static DataSource contextDataSource;
49    private static int factoryLoginTimeout = 1;
50    private static int providerLoginTimeout = 2;
51  
52    @BeforeAll
53    static void beforeClass() throws Throwable {
54      System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
55      System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
56      dataSourceName = "dataSource";
57      contextName = "jdbc";
58      globalDataSource = mock(DataSource.class);
59      contextDataSource = mock(DataSource.class);
60      InitialContext ic = new InitialContext();
61      ic.createSubcontext(contextName);
62      ic.bind(dataSourceName, globalDataSource);
63      ic.bind(contextName + "/" + dataSourceName, contextDataSource);
64    }
65  
66    @Test
67    void get_NoContext() {
68      Injector injector = Guice.createInjector(new AbstractModule() {
69        @Override
70        protected void configure() {
71          bindConstant().annotatedWith(Names.named("jndi.dataSource")).to(dataSourceName);
72        }
73      });
74      JndiDataSourceProvider provider = injector.getInstance(JndiDataSourceProvider.class);
75  
76      DataSource dataSource = provider.get();
77  
78      assertEquals(globalDataSource, dataSource);
79      assertNotEquals(contextDataSource, dataSource);
80    }
81  
82    @Test
83    void get_Context() {
84      Injector injector = Guice.createInjector(new AbstractModule() {
85        @Override
86        protected void configure() {
87          bindConstant().annotatedWith(Names.named("jndi.dataSource")).to(dataSourceName);
88          bindConstant().annotatedWith(Names.named("jndi.initialContext")).to(contextName);
89        }
90      });
91      JndiDataSourceProvider provider = injector.getInstance(JndiDataSourceProvider.class);
92  
93      DataSource dataSource = provider.get();
94  
95      assertEquals(contextDataSource, dataSource);
96      assertNotEquals(globalDataSource, dataSource);
97    }
98  
99    @Test
100   void get_Environment() throws Throwable {
101     final String initialContextFactory = TestInitialContextFactory.class.getName();
102     final String environmentProviderUrl = getClass()
103         .getResource("/" + getClass().getName().replace(".", "/") + ".properties").toString();
104     Injector injector = Guice.createInjector(new AbstractModule() {
105       @Override
106       protected void configure() {
107         bindConstant().annotatedWith(Names.named("jndi.dataSource")).to(dataSourceName);
108         bindConstant().annotatedWith(Names.named(Context.INITIAL_CONTEXT_FACTORY)).to(initialContextFactory);
109         bindConstant().annotatedWith(Names.named(Context.PROVIDER_URL)).to(environmentProviderUrl);
110       }
111     });
112     JndiDataSourceProvider provider = injector.getInstance(JndiDataSourceProvider.class);
113 
114     DataSource dataSource = provider.get();
115 
116     assertEquals(globalDataSource, dataSource);
117     verify(globalDataSource).setLoginTimeout(factoryLoginTimeout);
118     verify(globalDataSource).setLoginTimeout(providerLoginTimeout);
119   }
120 
121   public static class TestInitialContextFactory implements InitialContextFactory {
122     @Override
123     public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
124       Context context = new javaURLContextFactory().getInitialContext(environment);
125       DataSource dataSource = (DataSource) context.lookup(dataSourceName);
126       try {
127         dataSource.setLoginTimeout(factoryLoginTimeout);
128       } catch (SQLException e) {
129         // Ignore.
130       }
131       if (environment.get(Context.PROVIDER_URL) != null) {
132         try {
133           dataSource.setLoginTimeout(providerLoginTimeout);
134         } catch (SQLException e) {
135           // Ignore.
136         }
137       }
138       return context;
139     }
140   }
141 }