View Javadoc
1   /*
2    *    Copyright 2009-2021 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    *       http://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.apache.ibatis.datasource.jndi;
17  
18  import static org.junit.jupiter.api.Assertions.assertEquals;
19  
20  import java.util.HashMap;
21  import java.util.Hashtable;
22  import java.util.Map;
23  import java.util.Properties;
24  
25  import javax.naming.Context;
26  import javax.naming.InitialContext;
27  import javax.naming.NamingException;
28  import javax.naming.spi.InitialContextFactory;
29  import javax.sql.DataSource;
30  
31  import org.apache.ibatis.BaseDataTest;
32  import org.apache.ibatis.datasource.DataSourceException;
33  import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
34  import org.junit.jupiter.api.BeforeEach;
35  import org.junit.jupiter.api.Test;
36  
37  class JndiDataSourceFactoryTest extends BaseDataTest {
38  
39    private static final String TEST_INITIAL_CONTEXT_FACTORY = MockContextFactory.class.getName();
40    private static final String TEST_INITIAL_CONTEXT = "/mypath/path/";
41    private static final String TEST_DATA_SOURCE = "myDataSource";
42    private UnpooledDataSource expectedDataSource;
43  
44    @BeforeEach
45    void setup() throws Exception {
46      expectedDataSource = createUnpooledDataSource(BLOG_PROPERTIES);
47    }
48  
49    @Test
50    void shouldRetrieveDataSourceFromJNDI() {
51      createJndiDataSource();
52      JndiDataSourceFactory factory = new JndiDataSourceFactory();
53      factory.setProperties(new Properties() {
54        {
55          setProperty(JndiDataSourceFactory.ENV_PREFIX + Context.INITIAL_CONTEXT_FACTORY, TEST_INITIAL_CONTEXT_FACTORY);
56          setProperty(JndiDataSourceFactory.INITIAL_CONTEXT, TEST_INITIAL_CONTEXT);
57          setProperty(JndiDataSourceFactory.DATA_SOURCE, TEST_DATA_SOURCE);
58        }
59      });
60      DataSource actualDataSource = factory.getDataSource();
61      assertEquals(expectedDataSource, actualDataSource);
62    }
63  
64    private void createJndiDataSource() {
65      try {
66        Properties env = new Properties();
67        env.put(Context.INITIAL_CONTEXT_FACTORY, TEST_INITIAL_CONTEXT_FACTORY);
68  
69        MockContext ctx = new MockContext(false);
70        ctx.bind(TEST_DATA_SOURCE, expectedDataSource);
71  
72        InitialContext initCtx = new InitialContext(env);
73        initCtx.bind(TEST_INITIAL_CONTEXT, ctx);
74      } catch (NamingException e) {
75        throw new DataSourceException("There was an error configuring JndiDataSourceTransactionPool. Cause: " + e, e);
76      }
77    }
78  
79    public static class MockContextFactory implements InitialContextFactory {
80      @Override
81      public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
82        return new MockContext(false);
83      }
84    }
85  
86    public static class MockContext extends InitialContext {
87      private static Map<String,Object> bindings = new HashMap<>();
88  
89      MockContext(boolean lazy) throws NamingException {
90        super(lazy);
91      }
92  
93      @Override
94      public Object lookup(String name) {
95        return bindings.get(name);
96      }
97  
98      @Override
99      public void bind(String name, Object obj) {
100       bindings.put(name, obj);
101     }
102   }
103 
104 }