001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.camel.processor.idempotent.jpa;
018
019 import java.util.List;
020 import javax.persistence.EntityManagerFactory;
021 import javax.persistence.Persistence;
022
023 import org.apache.camel.spi.IdempotentRepository;
024 import org.springframework.orm.jpa.JpaTemplate;
025 import org.springframework.orm.jpa.JpaTransactionManager;
026 import org.springframework.transaction.TransactionDefinition;
027 import org.springframework.transaction.TransactionStatus;
028 import org.springframework.transaction.support.TransactionCallback;
029 import org.springframework.transaction.support.TransactionTemplate;
030
031 /**
032 * @version $Revision: 782534 $
033 */
034 public class JpaMessageIdRepository implements IdempotentRepository<String> {
035 protected static final String QUERY_STRING = "select x from " + MessageProcessed.class.getName() + " x where x.processorName = ?1 and x.messageId = ?2";
036 private JpaTemplate jpaTemplate;
037 private String processorName;
038 private TransactionTemplate transactionTemplate;
039
040 public JpaMessageIdRepository(JpaTemplate template, String processorName) {
041 this(template, createTransactionTemplate(template), processorName);
042 }
043
044 public JpaMessageIdRepository(JpaTemplate template, TransactionTemplate transactionTemplate, String processorName) {
045 this.jpaTemplate = template;
046 this.processorName = processorName;
047 this.transactionTemplate = transactionTemplate;
048 }
049
050 public static JpaMessageIdRepository jpaMessageIdRepository(String persistenceUnit, String processorName) {
051 EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnit);
052 return jpaMessageIdRepository(new JpaTemplate(entityManagerFactory), processorName);
053 }
054
055 public static JpaMessageIdRepository jpaMessageIdRepository(JpaTemplate jpaTemplate, String processorName) {
056 return new JpaMessageIdRepository(jpaTemplate, processorName);
057 }
058
059 private static TransactionTemplate createTransactionTemplate(JpaTemplate jpaTemplate) {
060 TransactionTemplate transactionTemplate = new TransactionTemplate();
061 transactionTemplate.setTransactionManager(new JpaTransactionManager(jpaTemplate.getEntityManagerFactory()));
062 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
063 return transactionTemplate;
064 }
065
066 public boolean add(final String messageId) {
067 // Run this in single transaction.
068 Boolean rc = (Boolean)transactionTemplate.execute(new TransactionCallback() {
069 public Object doInTransaction(TransactionStatus arg0) {
070 List list = jpaTemplate.find(QUERY_STRING, processorName, messageId);
071 if (list.isEmpty()) {
072 MessageProcessed processed = new MessageProcessed();
073 processed.setProcessorName(processorName);
074 processed.setMessageId(messageId);
075 jpaTemplate.persist(processed);
076 jpaTemplate.flush();
077 return Boolean.TRUE;
078 } else {
079 return Boolean.FALSE;
080 }
081 }
082 });
083 return rc.booleanValue();
084 }
085
086 public boolean contains(final String messageId) {
087 // Run this in single transaction.
088 Boolean rc = (Boolean)transactionTemplate.execute(new TransactionCallback() {
089 public Object doInTransaction(TransactionStatus arg0) {
090 List list = jpaTemplate.find(QUERY_STRING, processorName, messageId);
091 if (list.isEmpty()) {
092 return Boolean.FALSE;
093 } else {
094 return Boolean.TRUE;
095 }
096 }
097 });
098 return rc.booleanValue();
099 }
100
101 public boolean remove(final String messageId) {
102 Boolean rc = (Boolean)transactionTemplate.execute(new TransactionCallback() {
103 public Object doInTransaction(TransactionStatus arg0) {
104 List list = jpaTemplate.find(QUERY_STRING, processorName, messageId);
105 if (list.isEmpty()) {
106 return Boolean.FALSE;
107 } else {
108 MessageProcessed processoed = (MessageProcessed) list.get(0);
109 jpaTemplate.remove(processoed);
110 jpaTemplate.flush();
111 return Boolean.TRUE;
112 }
113 }
114 });
115 return rc.booleanValue();
116 }
117
118 public boolean confirm(String s) {
119 // noop
120 return true;
121 }
122
123 }