Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceChangedOperationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceChangedOperationTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceChangedOperationTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceChangedOperationTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,53 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.operations; + +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.apache.zookeeper.KeeperException; +import org.apache.zookeeper.ZooKeeper; +import org.junit.Test; + +public class ExistenceChangedOperationTest extends ZooKeeperTestSupport { + + @Test + public void getStatsWhenNodeIsCreated() throws Exception { + String path = "/doesNotYetExist"; + ExistenceChangedOperation future = setupMonitor(path); + + client.create(path, "This is a test"); + assertEquals(path, future.get().getResult()); + assertNotNull(future.get().getStatistics()); + } + + @Test + public void getsNotifiedWhenNodeIsDeleted() throws Exception { + String path = "/soonToBeDeleted"; + client.create(path, "This is a test"); + ExistenceChangedOperation future = setupMonitor(path); + + client.delete(path); + assertEquals(path, future.get().getResult()); + assertNull(future.get().getStatistics()); + } + + private ExistenceChangedOperation setupMonitor(String path) throws KeeperException, InterruptedException { + ZooKeeper connection = getConnection(); + ExistenceChangedOperation future = new ExistenceChangedOperation(connection, path); + connection.exists(path, future); + return future; + } +}
Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceOperationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceOperationTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceOperationTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/ExistenceOperationTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,56 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.operations; + +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.apache.zookeeper.ZooKeeper; +import org.junit.Test; + +public class ExistenceOperationTest extends ZooKeeperTestSupport { + + @Test + public void okWhenNodeMustExistAndDoesExists() throws Exception { + client.create("/ergosum", "not a figment of your imagination"); + ZooKeeper connection = getConnection(); + + ExistsOperation exists = new ExistsOperation(connection, "/ergosum"); + assertTrue(exists.get().isOk()); + } + + @Test + public void notOkWhenNodeMustExistButDoesNotExist() throws Exception { + ZooKeeper connection = getConnection(); + ExistsOperation exists = new ExistsOperation(connection, "/figment"); + assertFalse(exists.get().isOk()); + } + + @Test + public void okWhenNodeMustNotExistAndDoesNotExists() throws Exception { + ZooKeeper connection = getConnection(); + ExistsOperation exists = new ExistsOperation(connection, "/figment", false); + assertTrue(exists.get().isOk()); + } + + @Test + public void notOkWhenNodeMustExistButDoesExist() throws Exception { + client.create("/i-exist-too", "not a figment of your imagination"); + ZooKeeper connection = getConnection(); + + ExistsOperation exists = new ExistsOperation(connection, "/i-exist-too", false); + assertFalse(exists.get().isOk()); + } +} Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/FutureEventDrivenOperationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/FutureEventDrivenOperationTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/FutureEventDrivenOperationTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/FutureEventDrivenOperationTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,65 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.operations; + +import org.apache.zookeeper.WatchedEvent; +import org.apache.zookeeper.Watcher.Event.EventType; +import org.apache.zookeeper.data.Stat; + +import org.junit.Test; +import static org.junit.Assert.assertEquals; + + +public class FutureEventDrivenOperationTest { + private String data = "Event Received"; + private Stat statistics = new Stat(); + + @Test + public void shouldWaitForEvents() throws Exception { + final FutureEventDrivenOperation<String> future = new FutureEventDrivenOperation<String>(null, "somepath", EventType.NodeCreated) { + + @Override + protected void installWatch() { + } + + @Override + public OperationResult<String> getResult() { + return new OperationResult<String>(data, statistics); + } + }; + + WatchedEvent event = new WatchedEvent(EventType.NodeCreated, null, "somepath"); + fireEventIn(future, event, 100); + assertEquals(data, future.get().getResult()); + assertEquals(statistics, future.get().getStatistics()); + assertEquals(event, future.getEvent()); + } + + private void fireEventIn(final FutureEventDrivenOperation<String> future, final WatchedEvent event, final int millisecondsTillFire) { + new Thread(new Runnable() { + + public void run() { + + try { + Thread.sleep(millisecondsTillFire); + future.process(event); + } catch (InterruptedException e) { + } + } + }).start(); + } +} Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/SetDataOperationTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/SetDataOperationTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/SetDataOperationTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/operations/SetDataOperationTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,71 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.operations; + +import java.util.concurrent.ExecutionException; + +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.apache.zookeeper.ZooKeeper; +import org.junit.Before; +import org.junit.Test; + +public class SetDataOperationTest extends ZooKeeperTestSupport { + + private ZooKeeper connection; + + @Before + public void setupConnection() { + connection = getConnection(); + } + + @Test + public void setData() throws Exception { + client.create("/one", testPayload); + SetDataOperation operation = new SetDataOperation(connection, "/one", "Updated".getBytes()); + OperationResult<byte[]> result = operation.get(); + verifyNodeContainsData("/one", "Updated".getBytes()); + assertEquals(1, result.getStatistics().getVersion()); + } + + @Test + public void setSpecificVersionOfData() throws Exception { + + client.create("/two", testPayload); + for (int x = 0; x < 10; x++) { + byte[] payload = ("Updated_" + x).getBytes(); + updateDataOnNode("/two", payload, x, x + 1); + verifyNodeContainsData("/two", payload); + } + } + + @Test + public void setWithNull() throws Exception { + + client.create("/three", testPayload); + updateDataOnNode("/three", null, -1, 1); + + } + + private void updateDataOnNode(String node, byte[] payload, int version, int expectedVersion) throws InterruptedException, ExecutionException, Exception { + SetDataOperation operation = new SetDataOperation(connection, node, payload); + operation.setVersion(version); + OperationResult<byte[]> result = operation.get(); + assertEquals(null, result.getException()); + verifyNodeContainsData(node, payload); + assertEquals(expectedVersion, result.getStatistics().getVersion()); + } +} Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/FailoverRoutePolicyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/FailoverRoutePolicyTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/FailoverRoutePolicyTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/FailoverRoutePolicyTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,115 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.policy; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.CamelContext; +import org.apache.camel.ExchangePattern; +import org.apache.camel.ProducerTemplate; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.commons.logging.LogFactory; +import org.junit.Test; + +public class FailoverRoutePolicyTest extends ZooKeeperTestSupport { + + protected CamelContext createCamelContext() throws Exception { + disableJMX(); + // set up the parent nodes used to control the election + client.createPersistent("/someapp", "App node to contain policy election nodes..."); + client.createPersistent("/someapp/somepolicy", "Node used by route policy to control active routes..."); + return super.createCamelContext(); + } + + @Test + public void masterSlaveScenarioContolledByPolicy() throws Exception { + ZookeeperPolicyEnforcedContext tetrisisMasterOfBlocks = createEnforcedContext("master"); + ZookeeperPolicyEnforcedContext slave = createEnforcedContext("slave"); + + // http://bit.ly/9gTlGe ;). Send messages to the master and the slave. + // The route is enabled in the master and gets through, but that sent to + // the slave context is rejected. + tetrisisMasterOfBlocks.sendMessageToEnforcedRoute("LIIIIIIIIIINNNNNNNNNEEEEEEE PEEEEEEICCCE", 1); + slave.sendMessageToEnforcedRoute("But lord there is no place for a square!??!", 0); + + // trigger failover by killing the master... then assert that the slave + // can now receive messages. + tetrisisMasterOfBlocks.shutdown(); + slave.sendMessageToEnforcedRoute("What a cruel and angry god...", 1); + } + + private static class ZookeeperPolicyEnforcedContext { + private CamelContext controlledContext; + private ProducerTemplate template; + private MockEndpoint mock; + private String routename; + + public ZookeeperPolicyEnforcedContext(String name) throws Exception { + controlledContext = new DefaultCamelContext(); + routename = name; + template = controlledContext.createProducerTemplate(); + mock = controlledContext.getEndpoint("mock:controlled", MockEndpoint.class); + controlledContext.addRoutes(new FailoverRoute(name)); + controlledContext.start(); + } + + public void sendMessageToEnforcedRoute(String message, int expected) throws InterruptedException { + mock.expectedMessageCount(expected); + try { + template.sendBody("vm:" + routename, ExchangePattern.InOut, message); + } catch (Exception e) { + if (expected > 0) { + fail("Expected messages..."); + } + } + mock.await(2, TimeUnit.SECONDS); + mock.assertIsSatisfied(1000); + } + + public void shutdown() throws Exception { + LogFactory.getLog(getClass()).debug("stopping"); + controlledContext.stop(); + LogFactory.getLog(getClass()).debug("stopped"); + } + } + + private ZookeeperPolicyEnforcedContext createEnforcedContext(String name) throws Exception, InterruptedException { + ZookeeperPolicyEnforcedContext context = new ZookeeperPolicyEnforcedContext(name); + delay(1000); + return context; + } + + public static class FailoverRoute extends RouteBuilder { + + private String routename; + + public FailoverRoute(String routename) { + // need names as if we use the same direct ep name in two contexts + // in the same vm shutting down one context shuts the endpoint for + // both. + this.routename = routename; + } + + public void configure() throws Exception { + ZooKeeperRoutePolicy policy = new ZooKeeperRoutePolicy("zoo:localhost:39913/someapp/somepolicy", 1); + from("vm:" + routename).routePolicy(policy).id(routename).to("mock:controlled"); + } + }; +} Added: camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/ZookeeperRoutePolicyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/ZookeeperRoutePolicyTest.java?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/ZookeeperRoutePolicyTest.java (added) +++ camel/trunk/components/camel-zookeeper/src/test/java/org/apache/camel/component/zookeeper/policy/ZookeeperRoutePolicyTest.java Wed Aug 24 22:31:37 2011 @@ -0,0 +1,48 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF 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.apache.camel.component.zookeeper.policy; + +import java.util.concurrent.TimeUnit; + +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.mock.MockEndpoint; +import org.apache.camel.component.zookeeper.ZooKeeperTestSupport; +import org.junit.Test; + +public class ZookeeperRoutePolicyTest extends ZooKeeperTestSupport { + + @Test + public void routeCanBeControlledByPolicy() throws Exception { + // set up the parent used to control the election + client.createPersistent("/someapp", "App node to contain policy election nodes..."); + client.createPersistent("/someapp/somepolicy", "Policy node used by route policy to control routes..."); + context.addRoutes(new ZooKeeperPolicyEnforcedRoute()); + + MockEndpoint mock = getMockEndpoint("mock:controlled"); + mock.setExpectedMessageCount(1); + sendBody("direct:policy-controlled", "This is a test"); + mock.await(5, TimeUnit.SECONDS); + mock.assertIsSatisfied(); + } + + public static class ZooKeeperPolicyEnforcedRoute extends RouteBuilder { + public void configure() throws Exception { + ZooKeeperRoutePolicy policy = new ZooKeeperRoutePolicy("zoo:localhost:39913/someapp/somepolicy", 1); + from("direct:policy-controlled").routePolicy(policy).to("mock:controlled"); + } + }; +} Added: camel/trunk/components/camel-zookeeper/src/test/resources/log4j.properties URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/resources/log4j.properties?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/resources/log4j.properties (added) +++ camel/trunk/components/camel-zookeeper/src/test/resources/log4j.properties Wed Aug 24 22:31:37 2011 @@ -0,0 +1,39 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF 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. +# + +# +# The logging properties used for eclipse testing, We want to see debug output on the console. +# + +log4j.rootLogger=DEBUG, file +#log4j.rootLogger=DEBUG, out + +log4j.logger.org.springframework=WARN +log4j.logger.org.apache.zookeeper=WARN +#log4j.logger.org.apache.camel=DEBUG + +# CONSOLE appender not used by default +log4j.appender.out=org.apache.log4j.ConsoleAppender +log4j.appender.out.layout=org.apache.log4j.PatternLayout +log4j.appender.out.layout.ConversionPattern=[%t] %c{1} %-5p %m%n + +# File appender +log4j.appender.file=org.apache.log4j.FileAppender +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n +log4j.appender.file.file=target/camel-core-test.log +log4j.appender.file.append=true \ No newline at end of file Added: camel/trunk/components/camel-zookeeper/src/test/resources/zkserver1.conf URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/resources/zkserver1.conf?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/resources/zkserver1.conf (added) +++ camel/trunk/components/camel-zookeeper/src/test/resources/zkserver1.conf Wed Aug 24 22:31:37 2011 @@ -0,0 +1,8 @@ +tickTime=200000 +dataDir=./target/zkdata/server1 +clientPort=2181 +initLimit=5 +syncLimit=2 +server.1=localhost:2887:3887 +server.2=localhost:2888:3888 +server.3=localhost:2889:3889 \ No newline at end of file Added: camel/trunk/components/camel-zookeeper/src/test/resources/zkserver2.conf URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/resources/zkserver2.conf?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/resources/zkserver2.conf (added) +++ camel/trunk/components/camel-zookeeper/src/test/resources/zkserver2.conf Wed Aug 24 22:31:37 2011 @@ -0,0 +1,8 @@ +tickTime=200000 +dataDir=./target/zkdata/server2 +clientPort=2182 +initLimit=5 +syncLimit=2 +server.1=localhost:2887:3887 +server.2=localhost:2888:3888 +server.3=localhost:2889:3889 \ No newline at end of file Added: camel/trunk/components/camel-zookeeper/src/test/resources/zkserver3.conf URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-zookeeper/src/test/resources/zkserver3.conf?rev=1161306&view=auto ============================================================================== --- camel/trunk/components/camel-zookeeper/src/test/resources/zkserver3.conf (added) +++ camel/trunk/components/camel-zookeeper/src/test/resources/zkserver3.conf Wed Aug 24 22:31:37 2011 @@ -0,0 +1,8 @@ +tickTime=200000 +dataDir=./target/zkdata/server3 +clientPort=2183 +initLimit=5 +syncLimit=2 +server.1=localhost:2887:3887 +server.2=localhost:2888:3888 +server.3=localhost:2889:3889 \ No newline at end of file Modified: camel/trunk/components/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/components/pom.xml?rev=1161306&r1=1161305&r2=1161306&view=diff ============================================================================== --- camel/trunk/components/pom.xml (original) +++ camel/trunk/components/pom.xml Wed Aug 24 22:31:37 2011 @@ -138,6 +138,7 @@ <module>camel-xmlsecurity</module> <module>camel-xmpp</module> <module>camel-xstream</module> + <module>camel-zookeeper</module> </modules> </project> Modified: camel/trunk/parent/pom.xml URL: http://svn.apache.org/viewvc/camel/trunk/parent/pom.xml?rev=1161306&r1=1161305&r2=1161306&view=diff ============================================================================== --- camel/trunk/parent/pom.xml (original) +++ camel/trunk/parent/pom.xml Wed Aug 24 22:31:37 2011 @@ -160,6 +160,7 @@ <xerces-version>2.9.1</xerces-version> <xalan-version>2.7.1</xalan-version> <xmlbeans-version>2.5.0</xmlbeans-version> + <zookeeper-version>3.3.3</zookeeper-version> <!-- used by camel archetypes --> <maven-compiler-plugin-version>2.3.2</maven-compiler-plugin-version> @@ -1421,6 +1422,13 @@ <version>${ftpserver-version}</version> </dependency> + <!-- optional zookeeper dependency --> + <dependency> + <groupId>org.apache.zookeeper</groupId> + <artifactId>zookeeper</artifactId> + <version>${zookeeper-version}</version> + </dependency> + <!-- blueprint --> <dependency> <groupId>org.apache.aries.blueprint</groupId>