Repository: camel Updated Branches: refs/heads/master 6bbc94f0d -> 303c0cc1d
CAMEL-7297 Add remote querying feature to camel-infinispan component Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/303c0cc1 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/303c0cc1 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/303c0cc1 Branch: refs/heads/master Commit: 303c0cc1d80ae9e23e0b3409492bdc248eb99aae Parents: 6bbc94f Author: Bilgin Ibryam <[email protected]> Authored: Sun Mar 16 12:09:54 2014 +0000 Committer: Bilgin Ibryam <[email protected]> Committed: Sun Mar 16 12:09:54 2014 +0000 ---------------------------------------------------------------------- components/camel-infinispan/pom.xml | 34 +++++ .../infinispan/InfinispanConfiguration.java | 10 ++ .../infinispan/InfinispanConstants.java | 1 + .../infinispan/InfinispanOperation.java | 61 ++++++-- .../infinispan/InfinispanProducer.java | 2 +- .../query/HavingQueryBuilderStrategy.java | 41 +++++ .../processor/query/QueryBuilderStrategy.java | 25 +++ .../apache/camel/component/infinispan/Book.java | 98 ++++++++++++ .../component/infinispan/BookMarshaller.java | 54 +++++++ .../infinispan/InfinispanEmbeddedQueryTest.java | 104 +++++++++++++ .../infinispan/InfinispanRemoteQueryTest.java | 151 +++++++++++++++++++ .../src/test/resources/book.proto | 7 + .../src/test/resources/book.protobin | 9 ++ 13 files changed, 587 insertions(+), 10 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/pom.xml ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/pom.xml b/components/camel-infinispan/pom.xml index 7095186..a74c4ad 100644 --- a/components/camel-infinispan/pom.xml +++ b/components/camel-infinispan/pom.xml @@ -51,6 +51,21 @@ <artifactId>infinispan-client-hotrod</artifactId> <version>${infinispan-version}</version> </dependency> + <dependency> + <groupId>org.infinispan</groupId> + <artifactId>infinispan-query-dsl</artifactId> + <version>${infinispan-version}</version> + </dependency> + <dependency> + <groupId>org.infinispan</groupId> + <artifactId>infinispan-remote-query-client</artifactId> + <version>${infinispan-version}</version> + </dependency> + <dependency> + <groupId>org.infinispan</groupId> + <artifactId>infinispan-query</artifactId> + <version>${infinispan-version}</version> + </dependency> <!-- testing --> <dependency> @@ -75,4 +90,23 @@ <scope>test</scope> </dependency> </dependencies> + <profiles> + <profile> + <id>integration-test-infinispan</id> + <activation> + <property> + <name>integration-test</name> + </property> + </activation> + <dependencies> + <dependency> + <groupId>org.infinispan</groupId> + <artifactId>infinispan-jboss-client</artifactId> + <version>${infinispan-version}</version> + <scope>system</scope> + <systemPath>${basedir}/jboss-client.jar</systemPath> + </dependency> + </dependencies> + </profile> + </profiles> </project> http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConfiguration.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConfiguration.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConfiguration.java index 187daf3..f5866eb 100644 --- a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConfiguration.java +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConfiguration.java @@ -20,6 +20,7 @@ import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import org.apache.camel.component.infinispan.processor.query.QueryBuilderStrategy; import org.infinispan.commons.api.BasicCacheContainer; public class InfinispanConfiguration { @@ -29,6 +30,7 @@ public class InfinispanConfiguration { private String command; private boolean sync = true; private Set<String> eventTypes; + private QueryBuilderStrategy queryBuilderStrategy; public String getCommand() { return command; @@ -81,4 +83,12 @@ public class InfinispanConfiguration { public void setEventTypes(String eventTypes) { this.eventTypes = new HashSet<String>(Arrays.asList(eventTypes.split(","))); } + + public QueryBuilderStrategy getQueryBuilderStrategy() { + return queryBuilderStrategy; + } + + public void setQueryBuilderStrategy(QueryBuilderStrategy queryBuilderStrategy) { + this.queryBuilderStrategy = queryBuilderStrategy; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConstants.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConstants.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConstants.java index 7654e74..d2613c4 100644 --- a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConstants.java +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanConstants.java @@ -27,5 +27,6 @@ interface InfinispanConstants { String GET = "CamelInfinispanOperationGet"; String REMOVE = "CamelInfinispanOperationRemove"; String CLEAR = "CamelInfinispanOperationClear"; + String QUERY = "CamelInfinispanOperationQuery"; String RESULT = "CamelInfinispanOperationResult"; } http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanOperation.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanOperation.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanOperation.java index ae8e18d..175fc9c 100644 --- a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanOperation.java +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanOperation.java @@ -16,22 +16,34 @@ */ package org.apache.camel.component.infinispan; +import java.util.List; + import org.apache.camel.Exchange; +import org.infinispan.Cache; +import org.infinispan.client.hotrod.RemoteCache; +import org.infinispan.client.hotrod.Search; import org.infinispan.commons.api.BasicCache; +import org.infinispan.query.SearchManager; +import org.infinispan.query.dsl.QueryBuilder; +import org.infinispan.query.dsl.QueryFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class InfinispanOperation { private static final transient Logger LOGGER = LoggerFactory.getLogger(InfinispanOperation.class); private final BasicCache<Object, Object> cache; + private final InfinispanConfiguration configuration; - public InfinispanOperation(BasicCache<Object, Object> cache) { + public InfinispanOperation(BasicCache<Object, Object> cache, InfinispanConfiguration configuration) { this.cache = cache; + this.configuration = configuration; } public void process(Exchange exchange) { Operation operation = getOperation(exchange); - operation.execute(cache, exchange); + operation.setBasicCache(cache); + operation.setConfiguration(configuration); + operation.execute(exchange); } private Operation getOperation(Exchange exchange) { @@ -46,31 +58,62 @@ public class InfinispanOperation { enum Operation { PUT { @Override - void execute(BasicCache<Object, Object> cache, Exchange exchange) { + void execute(Exchange exchange) { Object result = cache.put(getKey(exchange), getValue(exchange)); setResult(result, exchange); } }, GET { @Override - void execute(BasicCache<Object, Object> cache, Exchange exchange) { + void execute(Exchange exchange) { Object result = cache.get(getKey(exchange)); setResult(result, exchange); } }, REMOVE { @Override - void execute(BasicCache<Object, Object> cache, Exchange exchange) { + void execute(Exchange exchange) { Object result = cache.remove(getKey(exchange)); setResult(result, exchange); } - - }, CLEAR { @Override - void execute(BasicCache<Object, Object> cache, Exchange exchange) { + void execute(Exchange exchange) { cache.clear(); } + }, QUERY { + @Override + void execute(Exchange exchange) { + if (configuration.getQueryBuilderStrategy() == null) { + throw new RuntimeException("QueryBuilderStrategy is required for executing queries!"); + } + + QueryFactory factory; + if (cache instanceof RemoteCache) { + factory = Search.getQueryFactory((RemoteCache) cache); + } else { + SearchManager searchManager = org.infinispan.query.Search.getSearchManager((Cache) cache); + factory = searchManager.getQueryFactory(); + } + + QueryBuilder queryBuilder = configuration.getQueryBuilderStrategy().createQueryBuilder(factory); + if (queryBuilder == null) { + throw new RuntimeException("QueryBuilder not created!"); + } + List<?> result = queryBuilder.build().list(); + setResult(result, exchange); + } }; + InfinispanConfiguration configuration; + BasicCache cache; + + public void setConfiguration(InfinispanConfiguration configuration) { + this.configuration = configuration; + } + + public void setBasicCache(BasicCache cache) { + this.cache = cache; + } + void setResult(Object result, Exchange exchange) { exchange.getIn().setHeader(InfinispanConstants.RESULT, result); } @@ -83,7 +126,7 @@ public class InfinispanOperation { return exchange.getIn().getHeader(InfinispanConstants.VALUE); } - abstract void execute(BasicCache<Object, Object> cache, Exchange exchange); + abstract void execute(Exchange exchange); } } http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanProducer.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanProducer.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanProducer.java index 9e3037c..4063553 100644 --- a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanProducer.java +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/InfinispanProducer.java @@ -39,7 +39,7 @@ public class InfinispanProducer extends DefaultProducer { @Override public void process(Exchange exchange) throws Exception { - new InfinispanOperation(getCache(exchange)).process(exchange); + new InfinispanOperation(getCache(exchange), configuration).process(exchange); } @Override http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/HavingQueryBuilderStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/HavingQueryBuilderStrategy.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/HavingQueryBuilderStrategy.java new file mode 100644 index 0000000..47417c4 --- /dev/null +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/HavingQueryBuilderStrategy.java @@ -0,0 +1,41 @@ +/** + * 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.infinispan.processor.query; + +import org.infinispan.query.dsl.Query; +import org.infinispan.query.dsl.QueryBuilder; +import org.infinispan.query.dsl.QueryFactory; + +public class HavingQueryBuilderStrategy implements QueryBuilderStrategy { + private final Class aCLass; + private final String attribute; + private final String value; + + public HavingQueryBuilderStrategy(Class aCLass, String attribute, String value) { + this.aCLass = aCLass; + this.attribute = attribute; + this.value = value; + } + + @Override + public QueryBuilder<Query> createQueryBuilder(QueryFactory queryFactory) { + return queryFactory + .from(aCLass) + .having(attribute).eq(value) + .toBuilder(); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/QueryBuilderStrategy.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/QueryBuilderStrategy.java b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/QueryBuilderStrategy.java new file mode 100644 index 0000000..45395ec --- /dev/null +++ b/components/camel-infinispan/src/main/java/org/apache/camel/component/infinispan/processor/query/QueryBuilderStrategy.java @@ -0,0 +1,25 @@ +/** + * 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.infinispan.processor.query; + +import org.infinispan.query.dsl.Query; +import org.infinispan.query.dsl.QueryBuilder; +import org.infinispan.query.dsl.QueryFactory; + +public interface QueryBuilderStrategy { + QueryBuilder<Query> createQueryBuilder(QueryFactory queryFactory); +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/Book.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/Book.java b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/Book.java new file mode 100644 index 0000000..9bb4072 --- /dev/null +++ b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/Book.java @@ -0,0 +1,98 @@ +/** + * 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.infinispan; + +import java.io.Serializable; + +import org.hibernate.search.annotations.Analyze; +import org.hibernate.search.annotations.Field; +import org.hibernate.search.annotations.Indexed; +import org.hibernate.search.annotations.Store; + +@Indexed +public class Book implements Serializable { + private String id; + private String title; + private String isbn; + + public Book() { + } + + public Book(String id, String title, String isbn) { + this.id = id; + this.title = title; + this.isbn = isbn; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @Field(store = Store.YES, analyze = Analyze.NO) + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getIsbn() { + return isbn; + } + + public void setIsbn(String isbn) { + this.isbn = isbn; + } + + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Book book = (Book) o; + + if (id != null ? !id.equals(book.id) : book.id != null) { + return false; + } + if (isbn != null ? !isbn.equals(book.isbn) : book.isbn != null) { + return false; + } + if (title != null ? !title.equals(book.title) : book.title != null) { + return false; + } + + return true; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + (title != null ? title.hashCode() : 0); + result = 31 * result + (isbn != null ? isbn.hashCode() : 0); + return result; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/BookMarshaller.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/BookMarshaller.java b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/BookMarshaller.java new file mode 100644 index 0000000..fe5509b --- /dev/null +++ b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/BookMarshaller.java @@ -0,0 +1,54 @@ +/** + * 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.infinispan; + +import java.io.IOException; + +import org.infinispan.protostream.MessageMarshaller; + +public class BookMarshaller implements MessageMarshaller<Book> { + + @Override + public String getTypeName() { + return "org.apache.camel.component.infinispan.Book"; + } + + @Override + public Class<? extends Book> getJavaClass() { + return Book.class; + } + + @Override + public Book readFrom(ProtoStreamReader reader) throws IOException { + String id = reader.readString("id"); + String title = reader.readString("title"); + String isbn = reader.readString("isbn"); + + Book book = new Book(); + book.setId(id); + book.setTitle(title); + book.setIsbn(isbn); + return book; + } + + @Override + public void writeTo(ProtoStreamWriter writer, Book book) throws IOException { + writer.writeString("id", book.getId()); + writer.writeString("title", book.getTitle()); + writer.writeString("isbn", book.getIsbn()); + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanEmbeddedQueryTest.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanEmbeddedQueryTest.java b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanEmbeddedQueryTest.java new file mode 100644 index 0000000..3caaaac --- /dev/null +++ b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanEmbeddedQueryTest.java @@ -0,0 +1,104 @@ +/** + * 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.infinispan; + +import java.util.List; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.infinispan.processor.query.HavingQueryBuilderStrategy; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.infinispan.commons.api.BasicCache; +import org.infinispan.commons.api.BasicCacheContainer; +import org.infinispan.configuration.cache.Configuration; +import org.infinispan.configuration.cache.ConfigurationBuilder; +import org.infinispan.manager.DefaultCacheManager; +import org.junit.Before; +import org.junit.Test; +import static org.hamcrest.core.Is.is; + +public class InfinispanEmbeddedQueryTest extends CamelTestSupport { + protected BasicCacheContainer basicCacheContainer; + protected HavingQueryBuilderStrategy queryBuilderStrategy = + new HavingQueryBuilderStrategy(Book.class, "title", "Camel"); + + @Override + @Before + public void setUp() throws Exception { + Configuration infinispanConfiguration = new ConfigurationBuilder() + .indexing() + .enable() + .indexLocalOnly(true) + .addProperty("default.directory_provider", "ram") + .build(); + + basicCacheContainer = new DefaultCacheManager(infinispanConfiguration); + basicCacheContainer.start(); + super.setUp(); + } + + @Override + public void tearDown() throws Exception { + basicCacheContainer.stop(); + super.tearDown(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry registry = super.createRegistry(); + registry.bind("cacheContainer", basicCacheContainer); + registry.bind("queryBuilderStrategy", queryBuilderStrategy); + return registry; + } + + protected BasicCache<Object, Object> currentCache() { + return basicCacheContainer.getCache(); + } + + @Test + public void findsCacheEntryBasedOnTheValue() throws Exception { + Book camelBook = new Book("1", "Camel", "123"); + Book activeMQBook = new Book("2", "ActiveMQ", "124"); + + currentCache().put(camelBook.getId(), camelBook); + currentCache().put(activeMQBook.getId(), activeMQBook); + + Exchange exchange = template.send("direct:start", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(InfinispanConstants.OPERATION, InfinispanConstants.QUERY); + } + }); + + List<Book> result = exchange.getIn().getHeader(InfinispanConstants.RESULT, List.class); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(camelBook)); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start") + .to("infinispan://localhost?cacheContainer=#cacheContainer&queryBuilderStrategy=#queryBuilderStrategy"); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanRemoteQueryTest.java ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanRemoteQueryTest.java b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanRemoteQueryTest.java new file mode 100644 index 0000000..775c43f --- /dev/null +++ b/components/camel-infinispan/src/test/java/org/apache/camel/component/infinispan/InfinispanRemoteQueryTest.java @@ -0,0 +1,151 @@ +/** + * 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.infinispan; + +import java.io.IOException; +import java.io.InputStream; +import java.util.List; + +import javax.management.MBeanServerConnection; +import javax.management.ObjectName; +import javax.management.remote.JMXConnector; +import javax.management.remote.JMXConnectorFactory; +import javax.management.remote.JMXServiceURL; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.infinispan.processor.query.HavingQueryBuilderStrategy; +import org.apache.camel.impl.JndiRegistry; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.infinispan.client.hotrod.RemoteCacheManager; +import org.infinispan.client.hotrod.configuration.Configuration; +import org.infinispan.client.hotrod.configuration.ConfigurationBuilder; +import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller; +import org.infinispan.commons.util.Util; +import org.infinispan.protostream.SerializationContext; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Test; +import static org.hamcrest.core.Is.is; + +@Ignore(value = "Run with standalone Infinispan server that has indexing enabled. " + + "Also you need jboss-client.jar on the classpath to register book.protobin over JMX") +public class InfinispanRemoteQueryTest extends CamelTestSupport { + public static final String BOOK_PROTOBIN = "/book.protobin"; + public static final String SERVER_URL = "127.0.0.1"; + protected HavingQueryBuilderStrategy queryBuilderStrategy; + protected RemoteCacheManager cacheContainer; + + @Override + @Before + public void setUp() throws Exception { + Configuration config = new ConfigurationBuilder() + .addServers(SERVER_URL) + .marshaller(new ProtoStreamMarshaller()) + .build(); + + cacheContainer = new RemoteCacheManager(config); + queryBuilderStrategy = new HavingQueryBuilderStrategy(Book.class, "title", "Camel"); + + SerializationContext srcCtx = ProtoStreamMarshaller.getSerializationContext(cacheContainer); + srcCtx.registerProtofile(BOOK_PROTOBIN); + srcCtx.registerMarshaller(Book.class, new BookMarshaller()); + + updateServerSchema(); + + super.setUp(); + } + + @Override + protected JndiRegistry createRegistry() throws Exception { + JndiRegistry registry = super.createRegistry(); + registry.bind("cacheContainer", cacheContainer); + registry.bind("queryBuilderStrategy", queryBuilderStrategy); + return registry; + } + + @Test + public void findsCacheEntryBasedOnTheValue() throws Exception { + final Book camelBook = new Book("1", "Camel", "123"); + final Book activeMQBook = new Book("2", "ActiveMQ", "124"); + + Exchange request = template.request("direct:start", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(InfinispanConstants.KEY, camelBook.getId()); + exchange.getIn().setHeader(InfinispanConstants.VALUE, camelBook); + } + }); + + assertNull(request.getException()); + + request = template.request("direct:start", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(InfinispanConstants.KEY, activeMQBook.getId()); + exchange.getIn().setHeader(InfinispanConstants.VALUE, activeMQBook); + } + }); + + assertNull(request.getException()); + + Exchange exchange = template.send("direct:start", new Processor() { + @Override + public void process(Exchange exchange) throws Exception { + exchange.getIn().setHeader(InfinispanConstants.OPERATION, InfinispanConstants.QUERY); + } + }); + + List<Book> result = exchange.getIn().getHeader(InfinispanConstants.RESULT, List.class); + assertNull(exchange.getException()); + assertThat(result.size(), is(1)); + assertThat(result.get(0), is(camelBook)); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() { + from("direct:start") + .to("infinispan://localhost?cacheContainer=#cacheContainer&queryBuilderStrategy=#queryBuilderStrategy"); + } + }; + } + + private void updateServerSchema() throws Exception { + JMXServiceURL serviceURL = new JMXServiceURL("service:jmx:remoting-jmx://" + SERVER_URL + ":" + "9999"); + JMXConnector jmxConnector = JMXConnectorFactory.connect(serviceURL, null); + MBeanServerConnection mBeanServerConnection = jmxConnector.getMBeanServerConnection(); + + byte[] descriptor = readClasspathResource(BOOK_PROTOBIN); + ObjectName objName = new ObjectName("jboss.infinispan:type=RemoteQuery,name=\"local\",component=ProtobufMetadataManager"); + mBeanServerConnection.invoke(objName, "registerProtofile", new Object[]{descriptor}, new String[]{byte[].class.getName()}); + } + + private byte[] readClasspathResource(String classPathResource) throws IOException { + InputStream is = getClass().getResourceAsStream(classPathResource); + try { + return Util.readStream(is); + } finally { + if (is != null) { + is.close(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/resources/book.proto ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/resources/book.proto b/components/camel-infinispan/src/test/resources/book.proto new file mode 100644 index 0000000..f70a5db --- /dev/null +++ b/components/camel-infinispan/src/test/resources/book.proto @@ -0,0 +1,7 @@ +package org.apache.camel.component.infinispan; + +message Book { + required string id = 1; + required string title = 2; + required string isbn = 3; +} http://git-wip-us.apache.org/repos/asf/camel/blob/303c0cc1/components/camel-infinispan/src/test/resources/book.protobin ---------------------------------------------------------------------- diff --git a/components/camel-infinispan/src/test/resources/book.protobin b/components/camel-infinispan/src/test/resources/book.protobin new file mode 100644 index 0000000..27b3c69 --- /dev/null +++ b/components/camel-infinispan/src/test/resources/book.protobin @@ -0,0 +1,9 @@ + +d + +book.proto%org.apache.camel.component.infinispan"/ +Book + +id ( +title ( +isbn ( \ No newline at end of file
