| /* |
| * This file is part of the Eclipse Virgo project. |
| * |
| * Copyright (c) 2011 Chariot Solutions, LLC |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * dsklyut - initial contribution |
| */ |
| |
| package org.eclipse.virgo.kernel.deployer.test; |
| |
| import static org.eclipse.virgo.kernel.deployer.test.util.ConfigurationTestUtils.pollUntilFactoryInConfigurationAdmin; |
| import static org.eclipse.virgo.kernel.deployer.test.util.ConfigurationTestUtils.pollUntilFactoryNotInConfigurationAdmin; |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.assertNotNull; |
| import static org.junit.Assert.assertTrue; |
| |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.text.SimpleDateFormat; |
| import java.util.Calendar; |
| import java.util.Dictionary; |
| import java.util.Hashtable; |
| import java.util.Properties; |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import org.eclipse.virgo.nano.deployer.api.core.ApplicationDeployer; |
| import org.eclipse.virgo.nano.deployer.api.core.DeploymentIdentity; |
| import org.junit.After; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.cm.Configuration; |
| import org.osgi.service.cm.ConfigurationAdmin; |
| import org.osgi.service.cm.ManagedServiceFactory; |
| |
| /** |
| * Tests for Configuration artifacts that support ManagedServiceFactory |
| * |
| */ |
| public class FactoryConfigurationDeploymentTests extends AbstractDeployerIntegrationTest { |
| |
| private static final SimpleDateFormat TIMESTAMP_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); |
| |
| private static String getTimestamp() { |
| Calendar calendar = Calendar.getInstance(); |
| calendar.setTimeInMillis(System.currentTimeMillis()); |
| return "[" + TIMESTAMP_FORMAT.format(calendar.getTime()) + "]"; |
| } |
| |
| private ServiceReference<ApplicationDeployer> appDeployerServiceReference; |
| |
| private ApplicationDeployer appDeployer; |
| |
| private ServiceReference<ConfigurationAdmin> configAdminServiceReference; |
| |
| private ConfigurationAdmin configAdmin; |
| |
| @Before |
| public void setUp() { |
| this.appDeployerServiceReference = this.context.getServiceReference(ApplicationDeployer.class); |
| this.appDeployer = this.context.getService(this.appDeployerServiceReference); |
| this.configAdminServiceReference = this.context.getServiceReference(ConfigurationAdmin.class); |
| this.configAdmin = this.context.getService(this.configAdminServiceReference); |
| } |
| |
| @After |
| public void tearDown() { |
| if (this.appDeployerServiceReference != null) { |
| this.context.ungetService(this.appDeployerServiceReference); |
| } |
| if (this.configAdminServiceReference != null) { |
| this.context.ungetService(this.configAdminServiceReference); |
| } |
| } |
| |
| @SuppressWarnings("rawtypes") |
| private static class TestManagedServiceFactory implements ManagedServiceFactory { |
| |
| private volatile Dictionary properties; |
| |
| private final AtomicInteger updateCallCount = new AtomicInteger(0); |
| |
| private final AtomicInteger deleteCallCount = new AtomicInteger(0); |
| |
| @Override |
| public String getName() { |
| return "Test Managed Service Factory"; |
| } |
| |
| @Override |
| public void updated(String pid, Dictionary properties) { |
| System.out.println(getTimestamp() + " updated pid '" + pid + "' with properties '" + properties + "'"); |
| this.updateCallCount.incrementAndGet(); |
| this.properties = properties; |
| } |
| |
| @Override |
| public void deleted(String pid) { |
| this.deleteCallCount.incrementAndGet(); |
| } |
| |
| Dictionary getProperties() { |
| return this.properties; |
| } |
| |
| int updateCount() { |
| return this.updateCallCount.get(); |
| } |
| |
| int deleteCount() { |
| return this.deleteCallCount.get(); |
| } |
| } |
| |
| @Test |
| @SuppressWarnings("rawtypes") |
| public void testSimpleDeployUndeployOfFactoryConfig() throws Exception { |
| |
| Hashtable<String, String> properties = new Hashtable<>(); |
| properties.put(Constants.SERVICE_PID, "test.factory.pid.a"); |
| TestManagedServiceFactory service = new TestManagedServiceFactory(); |
| this.context.registerService(ManagedServiceFactory.class, service, properties); |
| |
| // make sure that we are starting off with a clean slate |
| assertEquals(0, countFactoryConfigurations("test.factory.pid.a")); |
| |
| File configurationFile = new File("src/test/resources/configuration.deployment/factory-config-a.properties"); |
| |
| DeploymentIdentity deploymentIdentity = this.appDeployer.deploy(configurationFile.toURI()); |
| assertNotNull(deploymentIdentity); |
| |
| // let it deploy |
| sleep(100); |
| |
| assertEquals(1, countFactoryConfigurations("test.factory.pid.a")); |
| assertEquals(1, service.updateCount()); |
| assertEquals(0, service.deleteCount()); |
| Dictionary propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop1", propertiesFromService.get("prop1")); |
| assertEquals("2", propertiesFromService.get("prop2")); |
| |
| this.appDeployer.undeploy(deploymentIdentity); |
| |
| // give time for events to percolate |
| sleep(100); |
| assertEquals(0, countFactoryConfigurations("test.factory.pid.a")); |
| assertEquals(1, service.updateCount()); |
| assertEquals(1, service.deleteCount()); |
| |
| // now lets make sure that we can deploy it again |
| deploymentIdentity = this.appDeployer.deploy(configurationFile.toURI()); |
| sleep(1000); |
| assertEquals(1, countFactoryConfigurations("test.factory.pid.a")); |
| assertEquals(2, service.updateCount()); |
| assertEquals(1, service.deleteCount()); |
| |
| this.appDeployer.undeploy(deploymentIdentity); |
| } |
| |
| @Test |
| @SuppressWarnings("rawtypes") |
| public void testHotDeployFactoryConfiguration() throws Exception { |
| |
| final String factoryPid = "test.factory.pid.hot"; |
| final Properties hotDeployConfiguration = new Properties(); |
| hotDeployConfiguration.setProperty(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid); |
| hotDeployConfiguration.setProperty("prop1", "prop1"); |
| hotDeployConfiguration.setProperty("prop2", "2"); |
| |
| File target = new File("build/pickup/factory-config-a-hot.properties"); |
| |
| if (target.exists()) { |
| assertTrue(target.delete()); |
| } |
| |
| try { |
| Hashtable<String, String> properties = new Hashtable<>(); |
| properties.put(Constants.SERVICE_PID, factoryPid); |
| TestManagedServiceFactory service = new TestManagedServiceFactory(); |
| this.context.registerService(ManagedServiceFactory.class, service, properties); |
| |
| // make sure that we are starting off with a clean slate |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| |
| // copy file to hot deploy location |
| writePropertiesFile(hotDeployConfiguration, target, "no comment"); |
| |
| pollUntilFactoryInConfigurationAdmin(this.configAdmin, factoryPid); |
| // let events propagate |
| sleep(100); |
| assertEquals(1, countFactoryConfigurations(factoryPid)); |
| assertEquals(1, service.updateCount()); |
| assertEquals(0, service.deleteCount()); |
| |
| Dictionary propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop1", propertiesFromService.get("prop1")); |
| assertEquals("2", propertiesFromService.get("prop2")); |
| |
| // remove the file and let it be removed |
| target.delete(); |
| pollUntilFactoryNotInConfigurationAdmin(this.configAdmin, factoryPid); |
| // let events propagate |
| sleep(100); |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| assertEquals(1, service.updateCount()); |
| assertEquals(1, service.deleteCount()); |
| } finally { |
| if (target.exists()) { |
| target.delete(); |
| } |
| } |
| |
| } |
| |
| @Test |
| @SuppressWarnings("rawtypes") |
| public void testHotDeployWithUpdateFactoryConfiguration() throws Exception { |
| |
| final String factoryPid = "test.factory.pid.hot.update"; |
| final Properties hotDeployConfiguration = new Properties(); |
| hotDeployConfiguration.setProperty(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid); |
| hotDeployConfiguration.setProperty("prop1", "prop1"); |
| hotDeployConfiguration.setProperty("prop2", "2"); |
| |
| File target = new File("build/pickup/factory-config-a-hot-update.properties"); |
| |
| if (target.exists()) { |
| assertTrue(target.delete()); |
| } |
| |
| try { |
| |
| Hashtable<String, String> properties = new Hashtable<>(); |
| properties.put(Constants.SERVICE_PID, factoryPid); |
| TestManagedServiceFactory service = new TestManagedServiceFactory(); |
| this.context.registerService(ManagedServiceFactory.class, service, properties); |
| |
| // make sure that we are starting off with a clean slate |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| |
| writePropertiesFile(hotDeployConfiguration, target, "initial"); |
| |
| pollUntilFactoryInConfigurationAdmin(this.configAdmin, factoryPid); |
| // let events propagate |
| sleep(100); |
| assertEquals(1, countFactoryConfigurations(factoryPid)); |
| assertEquals(1, service.updateCount()); |
| assertEquals(0, service.deleteCount()); |
| |
| Dictionary propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop1", propertiesFromService.get("prop1")); |
| assertEquals("2", propertiesFromService.get("prop2")); |
| |
| // update configuration |
| hotDeployConfiguration.setProperty("prop2", "22"); |
| // save updated configuration |
| writePropertiesFile(hotDeployConfiguration, target, "updated"); |
| |
| // let events propagate and update happen |
| sleep(4001); |
| assertEquals(1, countFactoryConfigurations(factoryPid)); |
| assertEquals(2, service.updateCount()); // This takes several seconds to change from 1 to 2 |
| assertEquals(0, service.deleteCount()); |
| |
| propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop1", propertiesFromService.get("prop1")); |
| assertEquals("22", propertiesFromService.get("prop2")); |
| |
| // remove the file and let it be removed |
| target.delete(); |
| pollUntilFactoryNotInConfigurationAdmin(this.configAdmin, factoryPid); |
| |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| assertEquals(2, service.updateCount()); |
| assertEquals(1, service.deleteCount()); |
| } finally { |
| if (target.exists()) { |
| target.delete(); |
| } |
| } |
| } |
| |
| private static void sleep(long millis) throws InterruptedException { |
| System.out.println(getTimestamp() + " entered sleep(" + millis + ")"); |
| Thread.sleep(millis); |
| System.out.println(getTimestamp() + " exited sleep(" + millis + ")"); |
| } |
| |
| private void writePropertiesFile(final Properties hotDeployConfiguration, File target, String comment) throws IOException { |
| FileOutputStream stream = new FileOutputStream(target); |
| hotDeployConfiguration.store(stream, comment); |
| stream.flush(); |
| stream.close(); |
| } |
| |
| @Test |
| @SuppressWarnings("rawtypes") |
| public void testHotDeployMultipleFactoryConfiguration() throws Exception { |
| |
| final String factoryPid = "test.factory.pid.hot.multiple"; |
| |
| final Properties configOne = new Properties(); |
| configOne.setProperty(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid); |
| configOne.setProperty("prop1", "prop1"); |
| configOne.setProperty("prop2", "1"); |
| |
| final Properties configTwo = new Properties(); |
| configTwo.setProperty(ConfigurationAdmin.SERVICE_FACTORYPID, factoryPid); |
| configTwo.setProperty("prop1", "prop2"); |
| configTwo.setProperty("prop2", "2"); |
| |
| final File targetOne = new File("build/pickup/factory-config-a-hot-update-1.properties"); |
| final File targetTwo = new File("build/pickup/factory-config-a-hot-update-2.properties"); |
| |
| if (targetOne.exists()) { |
| assertTrue(targetOne.delete()); |
| } |
| if (targetTwo.exists()) { |
| assertTrue(targetTwo.delete()); |
| } |
| |
| try { |
| |
| Hashtable<String, String> properties = new Hashtable<>(); |
| properties.put(Constants.SERVICE_PID, factoryPid); |
| TestManagedServiceFactory service = new TestManagedServiceFactory(); |
| this.context.registerService(ManagedServiceFactory.class, service, properties); |
| |
| // make sure that we are starting off with a clean slate |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| |
| // copy file to hot deploy location |
| writePropertiesFile(configOne, targetOne, "initial"); |
| |
| pollUntilFactoryInConfigurationAdmin(this.configAdmin, factoryPid); |
| // let events propagate |
| sleep(100); |
| assertEquals(1, countFactoryConfigurations(factoryPid)); |
| assertEquals(1, service.updateCount()); |
| assertEquals(0, service.deleteCount()); |
| |
| // validate first configuration |
| Dictionary propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop1", propertiesFromService.get("prop1")); |
| assertEquals("1", propertiesFromService.get("prop2")); |
| |
| writePropertiesFile(configTwo, targetTwo, "initial"); |
| sleep(4002); |
| assertEquals(2, countFactoryConfigurations(factoryPid)); |
| assertEquals(2, service.updateCount()); |
| assertEquals(0, service.deleteCount()); |
| |
| propertiesFromService = service.getProperties(); |
| assertNotNull(propertiesFromService); |
| assertEquals("prop2", propertiesFromService.get("prop1")); |
| assertEquals("2", propertiesFromService.get("prop2")); |
| |
| assertTrue(targetOne.delete()); |
| assertTrue(targetTwo.delete()); |
| |
| // let events propagate and update happen |
| pollUntilFactoryNotInConfigurationAdmin(this.configAdmin, factoryPid); |
| assertEquals(0, countFactoryConfigurations(factoryPid)); |
| assertEquals(2, service.updateCount()); |
| assertEquals(2, service.deleteCount()); |
| |
| } finally { |
| if (targetOne.exists()) { |
| targetOne.delete(); |
| } |
| if (targetTwo.exists()) { |
| targetTwo.delete(); |
| } |
| } |
| } |
| |
| private int countFactoryConfigurations(String factoryPid) throws Exception { |
| Configuration[] configurations = this.configAdmin.listConfigurations(null); |
| int counter = 0; |
| for (Configuration c : configurations) { |
| if (factoryPid.equals(c.getFactoryPid())) { |
| counter++; |
| } |
| } |
| return counter; |
| } |
| } |