View Javadoc
1   /*
2    *    Copyright 2009-2023 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.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        private static final long serialVersionUID = 1L;
55        {
56          setProperty(JndiDataSourceFactory.ENV_PREFIX + Context.INITIAL_CONTEXT_FACTORY, TEST_INITIAL_CONTEXT_FACTORY);
57          setProperty(JndiDataSourceFactory.INITIAL_CONTEXT, TEST_INITIAL_CONTEXT);
58          setProperty(JndiDataSourceFactory.DATA_SOURCE, TEST_DATA_SOURCE);
59        }
60      });
61      DataSource actualDataSource = factory.getDataSource();
62      assertEquals(expectedDataSource, actualDataSource);
63    }
64  
65    private void createJndiDataSource() {
66      try {
67        Properties env = new Properties();
68        env.put(Context.INITIAL_CONTEXT_FACTORY, TEST_INITIAL_CONTEXT_FACTORY);
69  
70        MockContext ctx = new MockContext(false);
71        ctx.bind(TEST_DATA_SOURCE, expectedDataSource);
72  
73        InitialContext initCtx = new InitialContext(env);
74        initCtx.bind(TEST_INITIAL_CONTEXT, ctx);
75      } catch (NamingException e) {
76        throw new DataSourceException("There was an error configuring JndiDataSourceTransactionPool. Cause: " + e, e);
77      }
78    }
79  
80    public static class MockContextFactory implements InitialContextFactory {
81      @Override
82      public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException {
83        return new MockContext(false);
84      }
85    }
86  
87    public static class MockContext extends InitialContext {
88      private static final Map<String, Object> bindings = new HashMap<>();
89  
90      MockContext(boolean lazy) throws NamingException {
91        super(lazy);
92      }
93  
94      @Override
95      public Object lookup(String name) {
96        return bindings.get(name);
97      }
98  
99      @Override
100     public void bind(String name, Object obj) {
101       bindings.put(name, obj);
102     }
103   }
104 
105 }