/**
* 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.etcd;
import mousio.etcd4j.EtcdClient;
import mousio.etcd4j.responses.EtcdErrorCode;
import mousio.etcd4j.responses.EtcdException;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.mock.MockEndpoint;
import org.junit.Test;
public class EtcdWatchTest extends EtcdTestSupport {
@Test
public void testWatchWithPath() throws Exception {
testWatch("mock:watch-with-path", "/myKey1", 10);
}
@Test
public void testWatchWithConfigPath() throws Exception {
testWatch("mock:watch-with-config-path", "/myKey2", 10);
}
@Test
public void testWatchRecursive() throws Exception {
testWatch("mock:watch-recursive", "/recursive/myKey1", 10);
}
@Test
public void testWatchRecovery() throws Exception {
final String key = "/myKeyRecovery";
final EtcdClient client = getClient();
try {
// Delete the key if present
client.delete(key).send().get();
} catch (EtcdException e) {
if (!e.isErrorCode(EtcdErrorCode.KeyNotFound)) {
throw e;
}
}
// Fill the vent backlog ( > 1000)
for (int i = 0; i < 2000; i++) {
client.put(key, "v" + i).send().get();
}
context().startRoute("watchRecovery");
testWatch("mock:watch-recovery", key, 10);
}
@Test
public void testWatchWithTimeout() throws Exception {
MockEndpoint mock = getMockEndpoint("mock:watch-with-timeout");
mock.expectedMessageCount(1);
mock.expectedHeaderReceived(EtcdConstants.ETCD_NAMESPACE, EtcdNamespace.watch.name());
mock.expectedHeaderReceived(EtcdConstants.ETCD_PATH, "/timeoutKey");
mock.expectedHeaderReceived(EtcdConstants.ETCD_TIMEOUT, true);
mock.allMessages().body().isNull();
mock.assertIsSatisfied();
}
private void testWatch(String mockEndpoint, final String key, int updates) throws Exception {
final String[] values = new String[updates];
for (int i = 0; i < updates; i++) {
values[i] = key + "=myValue-" + i;
}
MockEndpoint mock = getMockEndpoint(mockEndpoint);
mock.expectedMessageCount(2);
mock.expectedHeaderReceived(EtcdConstants.ETCD_NAMESPACE, EtcdNamespace.watch.name());
mock.expectedHeaderReceived(EtcdConstants.ETCD_PATH, key);
mock.expectedBodiesReceived(values);
final EtcdClient client = getClient();
for (int i = 0; i < updates; i++) {
client.put(key, "myValue-" + i).send().get();
}
mock.assertIsSatisfied();
}
@Override
protected RouteBuilder createRouteBuilder() throws Exception {
return new RouteBuilder() {
public void configure() {
from("etcd:watch/myKey1")
.process(NODE_TO_VALUE_IN)
.to("mock:watch-with-path");
fromF("etcd:watch/myKeyRecovery?timeout=%s&fromIndex=%s", 1000 * 60 * 5, 1)
.id("watchRecovery")
.autoStartup(false)
.process(NODE_TO_VALUE_IN)
.to("mock:watch-recovery");
from("etcd:watch/recursive?recursive=true")
.process(NODE_TO_VALUE_IN)
.to("log:org.apache.camel.component.etcd?level=INFO")
.to("mock:watch-recursive");
from("etcd:watch/myKey2")
.process(NODE_TO_VALUE_IN)
.to("mock:watch-with-config-path");
from("etcd:watch/timeoutKey?timeout=250&sendEmptyExchangeOnTimeout=true")
.to("mock:watch-with-timeout");
}
};
}
}