/**
* Licensed to the Austrian Association for Software Tool Integration (AASTI)
* under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright
* ownership. The AASTI licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.openengsb.core.services.internal.deployer.connector;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.lessThan;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.fail;
import static org.junit.matchers.JUnitMatchers.hasItems;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyMap;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FileUtils;
import org.apache.shiro.SecurityUtils;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.mockito.ArgumentCaptor;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import org.openengsb.core.api.Connector;
import org.openengsb.core.api.ConnectorInstanceFactory;
import org.openengsb.core.api.ConnectorManager;
import org.openengsb.core.api.WiringService;
import org.openengsb.core.api.model.ConnectorDescription;
import org.openengsb.core.api.persistence.ConfigPersistenceService;
import org.openengsb.core.api.security.Credentials;
import org.openengsb.core.api.security.model.Authentication;
import org.openengsb.core.common.SecurityAttributeProviderImpl;
import org.openengsb.core.ekb.api.TransformationEngine;
import org.openengsb.core.persistence.internal.DefaultConfigPersistenceService;
import org.openengsb.core.services.OpenEngSBShiroAuthenticator;
import org.openengsb.core.services.internal.ConnectorManagerImpl;
import org.openengsb.core.services.internal.ConnectorRegistrationManager;
import org.openengsb.core.services.internal.DefaultWiringService;
import org.openengsb.core.services.internal.ForwardMethodInterceptor;
import org.openengsb.core.services.internal.security.OpenEngSBSecurityManager;
import org.openengsb.core.test.AbstractOsgiMockServiceTest;
import org.openengsb.core.test.DummyConfigPersistenceService;
import org.openengsb.core.test.NullDomain;
import org.openengsb.core.test.NullDomainImpl;
import org.openengsb.core.util.DefaultOsgiUtilsService;
import org.openengsb.core.util.MergeException;
import org.openengsb.domain.authentication.AuthenticationDomain;
import org.openengsb.domain.authentication.AuthenticationException;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import com.google.common.collect.ImmutableMap;
public class ConnectorDeployerServiceTest extends AbstractOsgiMockServiceTest {
private ConnectorDeployerService connectorDeployerService;
@Rule
public TemporaryFolder temporaryFolder = new TemporaryFolder();
private NullDomainImpl createdService;
private ConnectorManager serviceManager;
private static final String TEST_FILE_NAME = "test-connector-instance.connector";
private String testConnectorData = "domainType=mydomain\n"
+ "connectorType=aconnector\n"
+ "attribute.a-key=a-value";
private ConnectorInstanceFactory factory;
private String testConnectorId;
private DefaultConfigPersistenceService configPersistence;
private DefaultOsgiUtilsService serviceUtils;
private WiringService wiringService;
@Before
public void setUp() throws Exception {
connectorDeployerService = new ConnectorDeployerService();
connectorDeployerService.setBundleContext(bundleContext);
setupPersistence();
createServiceManagerMock();
connectorDeployerService.setServiceManager(serviceManager);
factory = mock(ConnectorInstanceFactory.class);
createdService = mock(NullDomainImpl.class);
when(factory.createNewInstance(anyString())).thenReturn(createdService);
when(factory.applyAttributes(any(Connector.class), anyMap())).thenAnswer(new Answer<Connector>() {
@Override
public Connector answer(InvocationOnMock invocation) throws Throwable {
return (Connector) invocation.getArguments()[0];
}
});
setupSecurityManager();
Dictionary<String, Object> props = new Hashtable<String, Object>();
props.put(org.openengsb.core.api.Constants.CONNECTOR_KEY, "aconnector");
props.put(org.openengsb.core.api.Constants.DOMAIN_KEY, "mydomain");
registerService(factory, props, ConnectorInstanceFactory.class);
createDomainProviderMock(NullDomain.class, "mydomain");
DefaultWiringService defaultWiringService = new DefaultWiringService();
defaultWiringService.setBundleContext(bundleContext);
registerServiceViaId(defaultWiringService, "wiring", WiringService.class);
testConnectorId = "test-connector-instance";
wiringService = defaultWiringService;
}
private void setupSecurityManager() throws AuthenticationException {
AuthenticationDomain authManager = mock(AuthenticationDomain.class);
when(authManager.authenticate(anyString(), any(Credentials.class))).thenAnswer(new Answer<Authentication>() {
@Override
public Authentication answer(InvocationOnMock invocation) throws Throwable {
String username = (String) invocation.getArguments()[0];
Credentials credentials = (Credentials) invocation.getArguments()[1];
return new Authentication(username, credentials);
}
});
OpenEngSBSecurityManager openEngSBSecurityManager = new OpenEngSBSecurityManager();
OpenEngSBShiroAuthenticator authenticator = new OpenEngSBShiroAuthenticator();
authenticator.setAuthenticator(authManager);
openEngSBSecurityManager.setAuthenticator(authenticator);
SecurityUtils.setSecurityManager(openEngSBSecurityManager);
}
private void setupPersistence() {
DummyConfigPersistenceService<ConnectorDescription> backend =
new DummyConfigPersistenceService<ConnectorDescription>();
configPersistence = new DefaultConfigPersistenceService(backend);
Dictionary<String, Object> props2 = new Hashtable<String, Object>();
props2.put("configuration.id", org.openengsb.core.api.Constants.CONFIG_CONNECTOR);
registerService(configPersistence, props2, ConfigPersistenceService.class);
}
private ConnectorManagerImpl createServiceManagerMock() {
ConnectorManagerImpl serviceManagerImpl = new ConnectorManagerImpl();
ConnectorRegistrationManager registrationManager = new ConnectorRegistrationManager(bundleContext,
mock(TransformationEngine.class), new ForwardMethodInterceptor(), new SecurityAttributeProviderImpl());
serviceUtils = new DefaultOsgiUtilsService(bundleContext);
serviceManagerImpl.setRegistrationManager(registrationManager);
serviceManagerImpl.setConfigPersistence(configPersistence);
serviceManager = serviceManagerImpl;
return serviceManagerImpl;
}
@Test
public void testConnectorFiles_shouldBeHandledByDeployer() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
assertThat(connectorDeployerService.canHandle(connectorFile), is(true));
}
@Test
public void testUnknownFiles_shouldNotBeHandledByDeplyoer() throws Exception {
File otherFile = temporaryFolder.newFile("other.txt");
assertThat(connectorDeployerService.canHandle(otherFile), is(false));
}
@Test
public void testConnectorFile_shouldBeInstalled() throws Exception {
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
NullDomain domainEndpoints = wiringService.getDomainEndpoint(NullDomain.class, "*");
domainEndpoints.nullMethod(42);
verify(createdService).nullMethod(42);
}
@Test
public void testConnectorFileWithArrays_shouldBeInstalled() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\nproperty.bla=foo,bar");
connectorDeployerService.install(connectorFile);
serviceUtils.getService("(bla=foo)", 100L);
serviceUtils.getService("(bla=bar)", 100L);
}
@Test
public void testConnectorFileWithRanking_shouldBeInstalledWithNumericRanking() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils
.writeStringToFile(connectorFile, testConnectorData + "\nproperty.service.ranking=2\nproperty.bla=foo");
connectorDeployerService.install(connectorFile);
serviceUtils.getService("(bla=foo)", 100L);
ServiceReference serviceReference = bundleContext.getServiceReferences((String) null, "(bla=foo)")[0];
Integer ranking = (Integer) serviceReference.getProperty(Constants.SERVICE_RANKING);
assertThat(ranking, notNullValue());
}
@Test
public void testConnectorFileWithArraysAndTrailingSpace_shouldBeInstalled() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\nproperty.bla=foo , bar");
connectorDeployerService.install(connectorFile);
serviceUtils.getService("(bla=foo)", 100L);
serviceUtils.getService("(bla=bar)", 100L);
}
private File createSampleConnectorFile() throws IOException {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeStringToFile(connectorFile, testConnectorData);
return connectorFile;
}
@SuppressWarnings("unchecked")
@Test
public void testUpdateConnectorFile_shouldBeUpdated() throws Exception {
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\nattribute.another=foo");
connectorDeployerService.update(connectorFile);
@SuppressWarnings("rawtypes")
ArgumentCaptor<Map> attributeCaptor = ArgumentCaptor.forClass(Map.class);
verify(factory, times(2)).applyAttributes(any(Connector.class), attributeCaptor.capture());
String value = (String) attributeCaptor.getAllValues().get(1).get("another");
assertThat(value, is("foo"));
}
@Test
public void testRootService_shouldHaveLowerRanking() throws Exception {
File connectorFile = new File(temporaryFolder.getRoot() + "/etc/mydomain+aconnector+myroot.connector");
FileUtils.touch(connectorFile);
FileUtils.writeStringToFile(connectorFile, testConnectorData);
connectorDeployerService.install(connectorFile);
ServiceReference reference = bundleContext.getServiceReferences(NullDomain.class.getName(), "")[0];
Integer ranking = (Integer) reference.getProperty(Constants.SERVICE_RANKING);
assertThat(ranking, lessThan(0));
}
@Test
public void testNormalService_shouldHaveNoRankingAdded() throws Exception {
File connectorFile = new File(temporaryFolder.getRoot() + "/config/mydomain+aconnector+myroot.connector");
FileUtils.touch(connectorFile);
FileUtils.writeStringToFile(connectorFile, testConnectorData);
connectorDeployerService.install(connectorFile);
ServiceReference reference = bundleContext.getServiceReferences(NullDomain.class.getName(), "")[0];
assertThat(reference.getProperty(Constants.SERVICE_RANKING), nullValue());
}
@Test
public void testOverridenRanking_shouldNotBeAltered() throws Exception {
File connectorFile = new File(temporaryFolder.getRoot() + "/etc/mydomain+aconnector+myroot.connector");
FileUtils.touch(connectorFile);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\n"
+ "property." + Constants.SERVICE_RANKING + "=24");
connectorDeployerService.install(connectorFile);
ServiceReference ref =
bundleContext.getServiceReferences(NullDomain.class.getName(),
String.format("(%s=%s)", Constants.SERVICE_RANKING, 24))[0];
assertThat(ref, not(nullValue()));
}
@Test
public void testUninstallService_shouldRemoveFromRegistry() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeStringToFile(connectorFile, testConnectorData);
connectorDeployerService.install(connectorFile);
connectorFile.delete();
connectorDeployerService.uninstall(connectorFile);
ServiceReference[] reference = bundleContext.getServiceReferences(NullDomain.class.getName(), "");
assertThat(reference, nullValue());
}
@Test
public void testUpdateService_shouldKeepInternalProperties() throws Exception {
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\nproperty.another=foo");
connectorDeployerService.update(connectorFile);
ServiceReference[] serviceReferences =
bundleContext.getServiceReferences(NullDomain.class.getName(), "(another=foo)");
assertThat(serviceReferences, not(nullValue()));
ServiceReference reference = serviceReferences[0];
assertThat((String) reference.getProperty(org.openengsb.core.api.Constants.CONNECTOR_KEY), is("aconnector"));
}
@Test
@Ignore
public void testInstallService_shouldNotOverwriteExistingService() throws Exception {
Map<String, Object> properties = new Hashtable<String, Object>();
properties.put("foo", "bar");
ConnectorDescription connectorDescription =
new ConnectorDescription("mydomain", "aconnector", null, properties);
serviceManager.createWithId(testConnectorId, connectorDescription);
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
ServiceReference[] references = bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar)");
assertThat("old service is not there anymore", references, not(nullValue()));
}
@Test
public void testUpdateService_shouldNotOverrideOtherwiseModifedProperties() throws Exception {
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
ConnectorDescription attributeValues = serviceManager.getAttributeValues(testConnectorId);
Map<String, Object> propertyValues = attributeValues.getProperties();
propertyValues.put("foo", "bar");
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
attributeValues.getAttributes(), propertyValues);
serviceManager.update(testConnectorId, newDesc);
FileUtils.writeStringToFile(connectorFile, testConnectorData + "\nproperty.foo=notbar");
try {
connectorDeployerService.update(connectorFile);
} catch (MergeException e) {
// expected
}
ServiceReference[] serviceReferences2 =
bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar)");
assertThat(serviceReferences2, not(nullValue()));
}
@Test
public void testUpdateServiceViaPersistence_shouldNotOverwriteProperties() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=y"));
connectorDeployerService.install(connectorFile);
ConnectorDescription desc =
serviceManager.getAttributeValues(testConnectorId);
desc.getProperties().put("foo", "42");
serviceManager.update(testConnectorId, desc);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=y", "property.x=y"));
connectorDeployerService.update(connectorFile);
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=42)"), not(nullValue()));
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(x=y)"), not(nullValue()));
}
@Test
public void testUpdateAttributeViaPersistence_shouldNotOverwrite() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=y"));
connectorDeployerService.install(connectorFile);
ConnectorDescription desc = serviceManager.getAttributeValues(testConnectorId);
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
ImmutableMap.of("x", "z"), desc.getProperties());
serviceManager.update(testConnectorId, newDesc);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=y", "property.x=y"));
connectorDeployerService.update(connectorFile);
ConnectorDescription attributeValues = serviceManager.getAttributeValues(testConnectorId);
assertThat(attributeValues.getAttributes().get("x"), is("z"));
}
@Test
public void testRemovePropertyFromConfig_shouldRemoveProperty() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=y"));
connectorDeployerService.install(connectorFile);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"attribute.x=y", "property.x=y"));
connectorDeployerService.update(connectorFile);
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar)"), nullValue());
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(x=y)"), not(nullValue()));
}
@Test
public void testModifyAttributeInBothPlaces_shouldThrowException() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=original-file-value"));
connectorDeployerService.install(connectorFile);
String id = testConnectorId;
ConnectorDescription desc = serviceManager.getAttributeValues(id);
Map<String, String> attributes = ImmutableMap.of("x", "new-persistence-value");
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
attributes, desc.getProperties());
serviceManager.update(id, newDesc);
FileUtils.writeLines(connectorFile,
Arrays.asList("property.foo=bar", "attribute.x=new-value-value"));
try {
connectorDeployerService.update(connectorFile);
fail("update should have failed, because of a merge-conflict");
} catch (MergeException e) {
assertThat(serviceManager.getAttributeValues(id).getAttributes().get("x"), is("new-persistence-value"));
}
}
@Test
public void testRemovePropertyOnBothEnds_shouldStayRemovedWithoutError() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=original-file-value"));
connectorDeployerService.install(connectorFile);
ConnectorDescription desc = serviceManager.getAttributeValues(testConnectorId);
Map<String, Object> properties = new Hashtable<String, Object>();
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
desc.getAttributes(), properties);
serviceManager.update(testConnectorId, newDesc);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"attribute.x=original-file-value"));
connectorDeployerService.update(connectorFile);
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar)"), nullValue());
}
@Test
public void testUpdateAttributeViaFileTwice_shouldUpdateTwice() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=43", "attribute.x=y"));
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=42", "attribute.x=y"));
connectorDeployerService.install(connectorFile);
connectorDeployerService.update(connectorFile);
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=43)"), nullValue());
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=42)"), not(nullValue()));
}
@Test
public void testUpdateFailure_shouldCreateBackupFile() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=original-file-value"));
connectorDeployerService.install(connectorFile);
String id = testConnectorId;
ConnectorDescription desc = serviceManager.getAttributeValues(id);
Map<String, String> attributes = ImmutableMap.of("x", "new-persistence-value");
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
attributes, desc.getProperties());
serviceManager.update(id, newDesc);
FileUtils.writeLines(connectorFile,
Arrays.asList("property.foo=bar", "attribute.x=new-value-value"));
try {
connectorDeployerService.update(connectorFile);
fail("update should have failed, because of a merge-conflict");
} catch (MergeException e) {
File backupFile = new File(temporaryFolder.getRoot(), TEST_FILE_NAME + "_001");
assertThat("no backup-file was created", backupFile.exists(), is(true));
}
}
@Test
@Ignore
public void testInstallFailure_shouldLeaveFileAsIs() throws Exception {
Map<String, Object> properties = new Hashtable<String, Object>();
properties.put("foo", "bar");
ConnectorDescription connectorDescription = new ConnectorDescription("mydomain", "aconnector",
new HashMap<String, String>(), properties);
serviceManager.createWithId(testConnectorId, connectorDescription);
File connectorFile = createSampleConnectorFile();
connectorDeployerService.install(connectorFile);
ServiceReference[] references = bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar)");
assertThat(connectorFile.exists(), is(true));
assertThat("old service is not there anymore", references, not(nullValue()));
}
@Test
public void testUpdateFailure_shouldReplaceWithOldConfigFile() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=original-file-value"));
connectorDeployerService.install(connectorFile);
String id = testConnectorId;
ConnectorDescription desc = serviceManager.getAttributeValues(id);
Map<String, String> attributes = ImmutableMap.of("x", "new-persistence-value");
ConnectorDescription newDesc = new ConnectorDescription("mydomain", "aconnector",
attributes, desc.getProperties());
serviceManager.update(id, newDesc);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=new-value-value"));
try {
connectorDeployerService.update(connectorFile);
fail("update should have failed, because of a merge-conflict");
} catch (MergeException e) {
List<String> lines = FileUtils.readLines(connectorFile);
assertThat(lines, hasItems("property.foo=bar", "attribute.x=original-file-value"));
}
}
@Test
public void testUpdateTwice_shouldUpdateCachedVersion() throws Exception {
File connectorFile = temporaryFolder.newFile(TEST_FILE_NAME);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar", "attribute.x=original-file-value"));
connectorDeployerService.install(connectorFile);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar2", "attribute.x=original-file-value"));
connectorDeployerService.update(connectorFile);
FileUtils.writeLines(connectorFile, Arrays.asList("domainType=mydomain", "connectorType=aconnector",
"property.foo=bar3", "attribute.x=original-file-value"));
connectorDeployerService.update(connectorFile);
assertThat(bundleContext.getServiceReferences(NullDomain.class.getName(), "(foo=bar3)"), not(nullValue()));
}
}