You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2013/10/12 10:46:18 UTC
git commit: CAMEL-6194: Added @PreConsumed to camel-jpa. Thanks to
Matt McCann for the patch.
Updated Branches:
refs/heads/master 099791206 -> 7ac3001e3
CAMEL-6194: Added @PreConsumed to camel-jpa. Thanks to Matt McCann for the patch.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/7ac3001e
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/7ac3001e
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/7ac3001e
Branch: refs/heads/master
Commit: 7ac3001e3f4ac0564383c39047e0d532435cf63b
Parents: 0997912
Author: Claus Ibsen <da...@apache.org>
Authored: Sat Oct 12 10:44:45 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Sat Oct 12 10:45:50 2013 +0200
----------------------------------------------------------------------
.../apache/camel/component/jpa/Consumed.java | 2 +-
.../camel/component/jpa/DeleteHandler.java | 3 +-
.../apache/camel/component/jpa/JpaConsumer.java | 53 +++++++++++++++-
.../apache/camel/component/jpa/PreConsumed.java | 33 ++++++++++
.../org/apache/camel/examples/SendEmail.java | 13 ++++
.../camel/processor/jpa/JpaPreConsumedTest.java | 65 ++++++++++++++++++++
6 files changed, 165 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
index 60c9bd4..94af889 100644
--- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
+++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/Consumed.java
@@ -23,7 +23,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * An annotation to mark a method to be invoked when an entity bean has been succesfully processed
+ * An annotation to mark a method to be invoked when an entity bean has been successfully processed
* by a Camel consumer and when the routing is done; so that it can be updated in some way to remove it from the query set.
* <p/>
* For example a method may be marked to set an active flag to false or to update some status value to the next step in a workflow
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/DeleteHandler.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/DeleteHandler.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/DeleteHandler.java
index b026073..f62da9d 100644
--- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/DeleteHandler.java
+++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/DeleteHandler.java
@@ -25,11 +25,12 @@ import javax.persistence.EntityManager;
* @version
*/
public interface DeleteHandler<T> {
+
/**
* Deletes the entity bean after it has been processed either by actually
* deleting the object or updating it in a way so that future queries do not return this object again.
*
- * @param entityManager
+ * @param entityManager the entity manager
* @param entityBean the entity bean that has been processed and should be deleted
*/
void deleteObject(EntityManager entityManager, Object entityBean);
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
index 8cfd3e8..e94c113 100644
--- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
+++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaConsumer.java
@@ -51,6 +51,7 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
private final TransactionTemplate transactionTemplate;
private QueryFactory queryFactory;
private DeleteHandler<Object> deleteHandler;
+ private DeleteHandler<Object> preDeleteHandler;
private String query;
private String namedQuery;
private String nativeQuery;
@@ -158,6 +159,9 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
pendingExchanges = total - index - 1;
if (lockEntity(result, entityManager)) {
+ // Run the @PreConsumed callback
+ createPreDeleteHandler().deleteObject(entityManager, result);
+
// process the current exchange
LOG.debug("Processing exchange: {}", exchange);
getProcessor().process(exchange);
@@ -166,6 +170,7 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
throw exchange.getException();
}
+ // Run the @Consumed callback
getDeleteHandler().deleteObject(entityManager, result);
}
}
@@ -204,7 +209,18 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
public void setDeleteHandler(DeleteHandler<Object> deleteHandler) {
this.deleteHandler = deleteHandler;
}
-
+
+ public DeleteHandler<Object> getPreDeleteHandler() {
+ if (preDeleteHandler == null) {
+ preDeleteHandler = createPreDeleteHandler();
+ }
+ return preDeleteHandler;
+ }
+
+ public void setPreDeleteHandler(DeleteHandler<Object> preDeleteHandler) {
+ this.preDeleteHandler = preDeleteHandler;
+ }
+
public void setParameters(Map<String, Object> params) {
this.parameters = params;
}
@@ -340,6 +356,40 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
}
}
+ protected DeleteHandler<Object> createPreDeleteHandler() {
+ // Look for @PreConsumed to allow custom callback before the Entity has been consumed
+ Class<?> entityType = getEndpoint().getEntityType();
+ if (entityType != null) {
+ // Inspect the method(s) annotated with @PreConsumed
+ List<Method> methods = ObjectHelper.findMethodsWithAnnotation(entityType, PreConsumed.class);
+ if (methods.size() > 1) {
+ throw new IllegalStateException("Only one method can be annotated with the @PreConsumed annotation but found: " + methods);
+ } else if (methods.size() == 1) {
+ // Inspect the parameters of the @PreConsumed method
+ Class<?>[] parameters = methods.get(0).getParameterTypes();
+ if (parameters.length != 0) {
+ throw new IllegalStateException("@PreConsumed annotated method cannot have parameters!");
+ }
+
+ final Method method = methods.get(0);
+ return new DeleteHandler<Object>() {
+ @Override
+ public void deleteObject(EntityManager entityManager, Object entityBean) {
+ ObjectHelper.invokeMethod(method, entityBean);
+ }
+ };
+ }
+ }
+
+ // else do nothing
+ return new DeleteHandler<Object>() {
+ @Override
+ public void deleteObject(EntityManager entityManager, Object entityBean) {
+ // Do nothing
+ }
+ };
+ }
+
protected DeleteHandler<Object> createDeleteHandler() {
// look for @Consumed to allow custom callback when the Entity has been consumed
Class<?> entityType = getEndpoint().getEntityType();
@@ -383,7 +433,6 @@ public class JpaConsumer extends ScheduledBatchPollingConsumer {
query.setParameter(entry.getKey(), entry.getValue());
}
}
-
}
protected Exchange createExchange(Object result) {
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/PreConsumed.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/PreConsumed.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/PreConsumed.java
new file mode 100644
index 0000000..5d65b13
--- /dev/null
+++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/PreConsumed.java
@@ -0,0 +1,33 @@
+/**
+ * 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.jpa;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * An annotation to mark a method to be invoked <b>before</b> an entity bean is processed and routed; so
+ * that it can be updated in such a way that the results are available to later nodes in the route.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ ElementType.METHOD })
+public @interface PreConsumed {
+}
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/test/java/org/apache/camel/examples/SendEmail.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/test/java/org/apache/camel/examples/SendEmail.java b/components/camel-jpa/src/test/java/org/apache/camel/examples/SendEmail.java
index 88650f1..408d68e 100644
--- a/components/camel-jpa/src/test/java/org/apache/camel/examples/SendEmail.java
+++ b/components/camel-jpa/src/test/java/org/apache/camel/examples/SendEmail.java
@@ -20,6 +20,10 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
+import org.apache.camel.component.jpa.PreConsumed;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
/**
* Represents a task which is added to the database, then removed from the database when it is consumed
*
@@ -27,6 +31,7 @@ import javax.persistence.Id;
*/
@Entity
public class SendEmail {
+ private static final Logger LOG = LoggerFactory.getLogger(SendEmail.class);
private Long id;
private String address;
@@ -59,4 +64,12 @@ public class SendEmail {
public void setAddress(String address) {
this.address = address;
}
+
+ @PreConsumed
+ public void doBefore() {
+ LOG.info("Invoked the pre consumed method with address {}", address);
+ if ("dummy".equals(address)) {
+ address = "dummy@somewhere.org";
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/camel/blob/7ac3001e/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaPreConsumedTest.java
----------------------------------------------------------------------
diff --git a/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaPreConsumedTest.java b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaPreConsumedTest.java
new file mode 100644
index 0000000..da4db29
--- /dev/null
+++ b/components/camel-jpa/src/test/java/org/apache/camel/processor/jpa/JpaPreConsumedTest.java
@@ -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.processor.jpa;
+
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.examples.SendEmail;
+import org.apache.camel.spring.SpringRouteBuilder;
+import org.junit.Test;
+
+/**
+ * @version
+ */
+public class JpaPreConsumedTest extends AbstractJpaTest {
+ protected static final String SELECT_ALL_STRING = "select x from " + SendEmail.class.getName() + " x";
+
+ @Test
+ public void testPreConsumed() throws Exception {
+ MockEndpoint mock = getMockEndpoint("mock:result");
+ mock.expectedMessageCount(1);
+
+ template.sendBody("direct:start", new SendEmail("dummy"));
+
+ assertMockEndpointsSatisfied();
+
+ // @PreConsumed should change the dummy address
+ SendEmail email = mock.getReceivedExchanges().get(0).getIn().getBody(SendEmail.class);
+ assertEquals("dummy@somewhere.org", email.getAddress());
+ }
+
+ @Override
+ protected RouteBuilder createRouteBuilder() {
+ return new SpringRouteBuilder() {
+ public void configure() {
+ from("direct:start").to("jpa://" + SendEmail.class.getName());
+
+ from("jpa://" + SendEmail.class.getName()).to("mock:result");
+ }
+ };
+ }
+
+ @Override
+ protected String routeXml() {
+ return "org/apache/camel/processor/jpa/springJpaRouteTest.xml";
+ }
+
+ @Override
+ protected String selectAllString() {
+ return SELECT_ALL_STRING;
+ }
+}
\ No newline at end of file