/**
* 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.ignite;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import com.google.common.base.Stopwatch;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.apache.camel.component.ignite.queue.IgniteQueueComponent;
import org.apache.camel.component.ignite.queue.IgniteQueueEndpoint;
import org.apache.camel.component.ignite.queue.IgniteQueueOperation;
import org.apache.camel.impl.JndiRegistry;
import org.apache.ignite.cache.CacheMode;
import org.apache.ignite.configuration.CollectionConfiguration;
import org.junit.After;
import org.junit.Test;
import static com.google.common.truth.Truth.assert_;
public class IgniteQueueTest extends AbstractIgniteTest {
@Override
protected String getScheme() {
return "ignite-queue";
}
@Override
protected AbstractIgniteComponent createComponent() {
return IgniteQueueComponent.fromConfiguration(createConfiguration());
}
@Test
public void testOperations() {
boolean result = template.requestBody("ignite-queue:abc?operation=ADD", "hello", boolean.class);
assert_().that(result).isTrue();
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).contains("hello")).isTrue();
result = template.requestBody("ignite-queue:abc?operation=CONTAINS", "hello", boolean.class);
assert_().that(result).isTrue();
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).contains("hello")).isTrue();
result = template.requestBody("ignite-queue:abc?operation=REMOVE", "hello", boolean.class);
assert_().that(result).isTrue();
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).contains("hello")).isFalse();
result = template.requestBody("ignite-queue:abc?operation=CONTAINS", "hello", boolean.class);
assert_().that(result).isFalse();
}
@Test
@SuppressWarnings("unchecked")
public void testOperations2() {
for (int i = 0; i < 100; i++) {
template.requestBody("ignite-queue:abc?operation=ADD", "hello" + i);
}
// SIZE
int size = template.requestBody("ignite-queue:abc?operation=SIZE", "hello", int.class);
assert_().that(size).isEqualTo(100);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(100);
List<String> toRetain = Lists.newArrayList();
for (int i = 0; i < 50; i++) {
toRetain.add("hello" + i);
}
// RETAIN_ALL
boolean retained = template.requestBodyAndHeader("ignite-queue:abc?operation=CLEAR", toRetain, IgniteConstants.IGNITE_QUEUE_OPERATION, IgniteQueueOperation.RETAIN_ALL, boolean.class);
assert_().that(retained).isTrue();
// SIZE
size = template.requestBody("ignite-queue:abc?operation=SIZE", "hello", int.class);
assert_().that(size).isEqualTo(50);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(50);
// ITERATOR
Iterator<String> iterator = template.requestBody("ignite-queue:abc?operation=ITERATOR", "hello", Iterator.class);
assert_().that(Iterators.toArray(iterator, String.class)).asList().containsExactlyElementsIn(toRetain).inOrder();
// ARRAY
String[] array = template.requestBody("ignite-queue:abc?operation=ARRAY", "hello", String[].class);
assert_().that(array).asList().containsExactlyElementsIn(toRetain).inOrder();
// CLEAR
Object result = template.requestBody("ignite-queue:abc?operation=CLEAR", "hello", String.class);
assert_().that(result).isEqualTo("hello");
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(0);
// SIZE
size = template.requestBody("ignite-queue:abc?operation=SIZE", "hello", int.class);
assert_().that(size).isEqualTo(0);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(0);
}
@Test
public void testRetainSingle() {
// Fill data.
for (int i = 0; i < 100; i++) {
template.requestBody("ignite-queue:abc?operation=ADD", "hello" + i);
}
boolean retained = template.requestBody("ignite-queue:abc?operation=RETAIN_ALL", "hello10", boolean.class);
assert_().that(retained).isTrue();
// ARRAY
String[] array = template.requestBody("ignite-queue:abc?operation=ARRAY", "hello", String[].class);
assert_().that(array).asList().containsExactly("hello10");
}
@Test
public void testCollectionsAsCacheObject() {
// Fill data.
for (int i = 0; i < 100; i++) {
template.requestBody("ignite-queue:abc?operation=ADD", "hello" + i);
}
// Add the set.
Set<String> toAdd = Sets.newHashSet("hello101", "hello102", "hello103");
template.requestBody("ignite-queue:abc?operation=ADD&treatCollectionsAsCacheObjects=true", toAdd);
// Size must be 101, not 103.
int size = template.requestBody("ignite-queue:abc?operation=SIZE", "hello", int.class);
assert_().that(size).isEqualTo(101);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(101);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).contains(toAdd)).isTrue();
// Check whether the Set contains the Set.
boolean contains = template.requestBody("ignite-queue:abc?operation=CONTAINS&treatCollectionsAsCacheObjects=true", toAdd, boolean.class);
assert_().that(contains).isTrue();
// Delete the Set.
template.requestBody("ignite-queue:abc?operation=REMOVE&treatCollectionsAsCacheObjects=true", toAdd);
// Size must be 100 again.
size = template.requestBody("ignite-queue:abc?operation=SIZE", "hello", int.class);
assert_().that(size).isEqualTo(100);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).size()).isEqualTo(100);
assert_().that(ignite().queue("abc", 0, new CollectionConfiguration()).contains(toAdd)).isFalse();
}
@Test
public void testWithConfiguration() {
CollectionConfiguration configuration = new CollectionConfiguration();
configuration.setCacheMode(CacheMode.LOCAL);
context.getRegistry(JndiRegistry.class).bind("config", configuration);
IgniteQueueEndpoint igniteEndpoint = context.getEndpoint("ignite-queue:abc?operation=ADD&configuration=#config", IgniteQueueEndpoint.class);
template.requestBody(igniteEndpoint, "hello");
assert_().that(ignite().queue("abc", 0, configuration).size()).isEqualTo(1);
assert_().that(igniteEndpoint.getConfiguration()).isEqualTo(configuration);
}
@Test
public void testBoundedQueueAndOtherOperations() throws Exception {
List<String> list = Lists.newArrayList();
// Fill data.
for (int i = 0; i < 100; i++) {
template.requestBody("ignite-queue:def?operation=ADD&capacity=100", "hello" + i);
list.add("hello" + i);
}
// NOTE: Unfortunately the behaviour of IgniteQueue doesn't adhere to the overridden ADD method. It should return an Exception.
assert_().that(template.requestBody("ignite-queue:def?operation=ADD&capacity=100", "hello101", boolean.class)).isFalse();
assert_().that(template.requestBody("ignite-queue:def?operation=OFFER&capacity=100", "hello101", boolean.class)).isFalse();
final CountDownLatch latch = new CountDownLatch(1);
Thread t = new Thread(new Runnable() {
@Override
public void run() {
assert_().that(template.requestBody("ignite-queue:def?operation=PUT&capacity=100", "hello101", boolean.class)).isFalse();
latch.countDown();
}
});
t.start();
// Wait 2 seconds and check that the thread was blocked.
assert_().that(latch.await(2000, TimeUnit.MILLISECONDS)).isFalse();
t.interrupt();
// PEEK and ELEMENT.
assert_().that(template.requestBody("ignite-queue:def?operation=PEEK&capacity=100", null, String.class)).isEqualTo("hello0");
assert_().that(template.requestBody("ignite-queue:def?operation=ELEMENT&capacity=100", null, String.class)).isEqualTo("hello0");
// TAKE.
assert_().that(template.requestBody("ignite-queue:def?operation=TAKE&capacity=100", null, String.class)).isEqualTo("hello0");
assert_().that(template.requestBody("ignite-queue:def?operation=SIZE&capacity=100", null, int.class)).isEqualTo(99);
// Now drain.
assert_().that(template.requestBody("ignite-queue:def?operation=DRAIN&capacity=100", null, String[].class)).asList().hasSize(99);
assert_().that(template.requestBody("ignite-queue:def?operation=SIZE&capacity=100", null, int.class)).isEqualTo(0);
assert_().that(template.requestBody("ignite-queue:def?operation=POLL&capacity=100", null, String.class)).isNull();
// TAKE.
t = new Thread(new Runnable() {
@Override
public void run() {
assert_().that(template.requestBody("ignite-queue:def?operation=TAKE&capacity=100", null, String.class)).isEqualTo("hello102");
latch.countDown();
}
});
t.start();
// Element was returned.
assert_().that(template.requestBody("ignite-queue:def?operation=ADD&capacity=100", "hello102", boolean.class)).isTrue();
assert_().that(latch.await(1000, TimeUnit.MILLISECONDS)).isTrue();
// POLL with a timeout.
assert_().that(Executors.newSingleThreadExecutor().submit(new Callable<Long>() {
@Override
public Long call() throws Exception {
Stopwatch sw = Stopwatch.createStarted();
assert_().that(template.requestBody("ignite-queue:def?operation=POLL&timeoutMillis=1000&capacity=100", null, String.class)).isNull();
return sw.elapsed(TimeUnit.MILLISECONDS);
}
}).get()).isAtLeast(1000L);
}
@Override
public boolean isCreateCamelContextPerClass() {
return true;
}
@After
public void deleteQueues() {
for (String queueName : ImmutableSet.<String> of("abc")) {
ignite().queue(queueName, 0, new CollectionConfiguration()).close();
}
// Bounded queues.
for (String queueName : ImmutableSet.<String> of("def")) {
ignite().queue(queueName, 100, new CollectionConfiguration()).close();
}
}
}