DataSourceConfigManager implements ManagedServiceFactory { @Override public void updated(final String pid, final Dictionary config) throws ConfigurationException { deleted(pid); if (config == null) { return; } Dictionary<String, Object> loadedConfig = externalConfigLoader.resolve(config); String seFilter = getStringEncryptorFilter(loadedConfig); String dsfFilter = getDSFFilter(loadedConfig); String pdsfFilter = getPooledDSFFilter(loadedConfig); String phFilter = getPreHookFilter(loadedConfig); ServiceTrackerHelper helper = ServiceTrackerHelper.helper(context); ServiceTracker<?, ?> tracker; if (Objects.nonNull(pdsfFilter)) { tracker = helper.track(StringEncryptor.class, seFilter, se -> helper.track(PooledDataSourceFactory.class, pdsfFilter, pdsf -> helper.track(PreHook.class, phFilter, ph -> helper.track(DataSourceFactory.class, dsfFilter, dsf -> new DataSourceRegistration(context, new PoolingWrapper(pdsf, dsf), loadedConfig, new Decryptor(se).decrypt(loadedConfig), ph), DataSourceRegistration::close)))); } else { tracker = helper.track(StringEncryptor.class, seFilter, se -> helper.track(PreHook.class, phFilter, ph -> helper.track(DataSourceFactory.class, dsfFilter, dsf -> new DataSourceRegistration(context, dsf, loadedConfig, new Decryptor(se).decrypt(loadedConfig), ph), DataSourceRegistration::close))); } trackers.put(pid, tracker); } DataSourceConfigManager(BundleContext context, ExternalConfigLoader externalConfigLoader); @Override String getName(); @Override void updated(final String pid, final Dictionary config); @Override synchronized void deleted(String pid);  }
@Test public void testUpdatedAndDeleted() throws Exception { DataSourceFactory dsf = expectTracked(c, context, DataSourceFactory.class, H2_DSF_FILTER); DataSource ds = expectDataSourceCreated(dsf); ServiceRegistration sreg = expectRegistration(ds); Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(DataSourceRegistration.JNDI_SERVICE_NAME, "test"); properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, H2_DRIVER_CLASS); properties.put(DataSourceFactory.JDBC_DATABASE_NAME, "mydbname"); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); dsManager.updated(TESTPID, properties); c.verify(); c.reset(); context.removeServiceListener(anyObject(ServiceListener.class)); expectLastCall().atLeastOnce(); sreg.unregister(); expectLastCall(); expect(context.ungetService(anyObject(ServiceReference.class))).andReturn(true).atLeastOnce(); c.replay(); dsManager.updated(TESTPID, null); c.verify(); }
@Test public void testPreHook() throws Exception { DataSourceFactory dsf = expectTracked(c, context, DataSourceFactory.class, H2_DSF_FILTER); DataSource ds = expectDataSourceCreated(dsf); ServiceRegistration sreg = expectRegistration(ds); PreHook preHook = expectTracked(c, context, PreHook.class, "(&(objectClass=org.ops4j.pax.jdbc.hook.PreHook)(name=myhook))"); preHook.prepare(anyObject(DataSource.class)); expectLastCall().once(); Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(DataSourceRegistration.JNDI_SERVICE_NAME, "test"); properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, H2_DRIVER_CLASS); properties.put(DataSourceFactory.JDBC_DATABASE_NAME, "mydbname"); properties.put(PreHook.CONFIG_KEY_NAME, "myhook"); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); dsManager.updated(TESTPID, properties); c.verify(); c.reset(); context.removeServiceListener(anyObject(ServiceListener.class)); expectLastCall().atLeastOnce(); sreg.unregister(); expectLastCall(); expect(context.ungetService(anyObject(ServiceReference.class))).andReturn(true).atLeastOnce(); c.replay(); dsManager.updated(TESTPID, null); c.verify(); }
@Test public void testNotEnoughInfoToFindDriver() { Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put("other", "value"); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); try { dsManager.updated(TESTPID, properties); } catch (ConfigurationException e) { assertEquals("Could not determine driver to use. " + "Specify either osgi.jdbc.driver.class or osgi.jdbc.driver.name", e.getReason()); } c.verify(); }
@Test public void testEncryptor() throws Exception { final DataSourceFactory dsf = expectTracked(c, context, DataSourceFactory.class, H2_DSF_FILTER); DataSource ds = c.createMock(DataSource.class); Capture<Properties> capturedProps = newCapture(); expect(dsf.createDataSource(EasyMock.capture(capturedProps))).andReturn(ds); expectRegistration(ds); StringEncryptor encryptor = expectTracked(c, context, StringEncryptor.class, "(objectClass=org.jasypt.encryption.StringEncryptor)"); expect(encryptor.decrypt("ciphertext")).andReturn("password"); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(DataSourceRegistration.JNDI_SERVICE_NAME, "test"); properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, H2_DRIVER_CLASS); properties.put(DataSourceFactory.JDBC_DATABASE_NAME, "mydbname"); properties.put(DataSourceFactory.JDBC_PASSWORD, "ENC(ciphertext)"); dsManager.updated(TESTPID, properties); c.verify(); assertEquals("ENC(ciphertext)", properties.get(DataSourceFactory.JDBC_PASSWORD)); assertEquals("password", capturedProps.getValue().get(DataSourceFactory.JDBC_PASSWORD)); }
@Test public void testEncryptorWithExternalSecret() throws Exception { final DataSourceFactory dsf = expectTracked(c, context, DataSourceFactory.class, H2_DSF_FILTER); DataSource ds = expectDataSourceCreated(dsf); expectRegistration(ds); StringEncryptor encryptor = expectTracked(c, context, StringEncryptor.class, "(objectClass=org.jasypt.encryption.StringEncryptor)"); expect(encryptor.decrypt("ciphertext")).andReturn("password"); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); Dictionary<String, String> properties = new Hashtable<String, String>(); properties.put(DataSourceRegistration.JNDI_SERVICE_NAME, "test"); properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, H2_DRIVER_CLASS); properties.put(DataSourceFactory.JDBC_DATABASE_NAME, "mydbname"); String externalEncryptedValue = "FILE(" + ExternalConfigLoaderTest .createExternalSecret("ENC(ciphertext)") + ")"; properties.put(DataSourceFactory.JDBC_PASSWORD, externalEncryptedValue); dsManager.updated(TESTPID, properties); c.verify(); assertEquals(externalEncryptedValue, properties.get(DataSourceFactory.JDBC_PASSWORD)); }
@Test public void testHiddenAndPropagation() throws Exception { final DataSourceFactory dsf = expectTracked(c, context, DataSourceFactory.class, H2_DSF_FILTER); final String keyHiddenJdbcPassword = "." + DataSourceFactory.JDBC_PASSWORD; final String keyNonlocalProperty = "nonlocal.property"; final String keyLocalProperty = "localproperty"; final String keyDatasourceType = "dataSourceType"; final String keyPoolProperty = "pool.maxTotal"; final String keyFactoryProperty = "factory.poolStatements"; final String valueLocalProperty = "something2"; final String dbname = "mydbname"; final String password = "thepassword"; final String user = "theuser"; final String poolMaxTotal = "10"; final String factoryPoolStatements = "true"; Hashtable<String, String> properties = new Hashtable<String, String>(); properties.put(DataSourceFactory.OSGI_JDBC_DRIVER_CLASS, H2_DRIVER_CLASS); properties.put(DataSourceFactory.JDBC_DATABASE_NAME, dbname); properties.put(DataSourceFactory.JDBC_USER, user); properties.put(keyHiddenJdbcPassword, password); properties.put(keyLocalProperty, valueLocalProperty); properties.put(keyNonlocalProperty, "something"); properties.put(keyPoolProperty, poolMaxTotal); properties.put(keyFactoryProperty, factoryPoolStatements); final String valueDatasourceName = "myDataSource"; properties.put(keyDatasourceType, "DataSource"); properties.put(DataSourceFactory.JDBC_DATASOURCE_NAME, valueDatasourceName); properties.put(DataSourceRegistration.MANAGED_DATASOURCE, "true"); Properties expectedDataSourceProperties = new Properties(); expectedDataSourceProperties.put(DataSourceFactory.JDBC_DATABASE_NAME, dbname); expectedDataSourceProperties.put(DataSourceFactory.JDBC_USER, user); expectedDataSourceProperties.put(DataSourceFactory.JDBC_PASSWORD, password); expectedDataSourceProperties.put(keyLocalProperty, valueLocalProperty); expectedDataSourceProperties.put(keyPoolProperty, poolMaxTotal); expectedDataSourceProperties.put(keyFactoryProperty, factoryPoolStatements); DataSource ds = expectDataSourceCreated(dsf); Hashtable<String, String> expectedServiceProperties = (Hashtable<String, String>)properties.clone(); expectedServiceProperties.remove(keyHiddenJdbcPassword); expectedServiceProperties.put("osgi.jndi.service.name", valueDatasourceName); ServiceRegistration sreg = c.createMock(ServiceRegistration.class); expect(context.registerService(anyString(), eq(ds), eq(expectedServiceProperties))).andReturn(sreg); c.replay(); DataSourceConfigManager dsManager = new DataSourceConfigManager(context, new ExternalConfigLoader(context)); dsManager.updated(TESTPID, properties); c.verify(); }