001/** 002 * Copyright 2015 DuraSpace, Inc. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.fcrepo.camel; 017 018import static org.slf4j.LoggerFactory.getLogger; 019 020import java.io.InputStream; 021import java.net.URI; 022 023import org.slf4j.Logger; 024import org.springframework.transaction.CannotCreateTransactionException; 025import org.springframework.transaction.TransactionDefinition; 026import org.springframework.transaction.TransactionSystemException; 027import org.springframework.transaction.support.AbstractPlatformTransactionManager; 028import org.springframework.transaction.support.DefaultTransactionStatus; 029 030/** 031 * A Transaction Manager for interacting with fedora-based transactions 032 * 033 * @author Aaron Coburn 034 * @since Feb 16, 2015 035 */ 036public class FcrepoTransactionManager extends AbstractPlatformTransactionManager { 037 038 private FcrepoClient client; 039 040 private String baseUrl; 041 042 private String authUsername; 043 044 private String authPassword; 045 046 private String authHost; 047 048 private static final Logger LOGGER = getLogger(FcrepoTransactionManager.class); 049 050 /** 051 * Create a FcrepoTransactionManager 052 */ 053 public FcrepoTransactionManager() { 054 super(); 055 setNestedTransactionAllowed(false); 056 } 057 058 /** 059 * Set the baseUrl for the transaction manager. 060 * 061 * @param baseUrl the fcrepo base url 062 */ 063 public void setBaseUrl(final String baseUrl) { 064 this.baseUrl = baseUrl; 065 } 066 067 /** 068 * Get the base url for the transaction manager. 069 * 070 * @return the fcrepo base url 071 */ 072 public String getBaseUrl() { 073 return baseUrl; 074 } 075 076 /** 077 * Set the authUsername for the transaction manager. 078 * 079 * @param authUsername the username for authentication 080 */ 081 public void setAuthUsername(final String authUsername) { 082 this.authUsername = authUsername; 083 } 084 085 /** 086 * Get the authUsername for the transaction manager. 087 * 088 * @return the username for authentication 089 */ 090 public String getAuthUsername() { 091 return authUsername; 092 } 093 094 /** 095 * Set the authPassword for the transaction manager. 096 * 097 * @param authPassword the password used for authentication 098 */ 099 public void setAuthPassword(final String authPassword) { 100 this.authPassword = authPassword; 101 } 102 103 /** 104 * Get the authPassword for the transaction manager. 105 * 106 * @return the password used for authentication 107 */ 108 public String getAuthPassword() { 109 return authPassword; 110 } 111 112 /** 113 * Set the authHost for the transaction manager. 114 * 115 * @param authHost the host realm used for authentication 116 */ 117 public void setAuthHost(final String authHost) { 118 this.authHost = authHost; 119 } 120 121 /** 122 * Get the authHost for the transaction manager. 123 * 124 * @return the host realm used for authentication 125 */ 126 public String getAuthHost() { 127 return authHost; 128 } 129 130 @Override 131 protected void doBegin(final Object transaction, final TransactionDefinition definition) { 132 final FcrepoResponse response; 133 final InputStream is = null; 134 final String contentType = null; 135 final FcrepoTransactionObject tx = (FcrepoTransactionObject)transaction; 136 137 if (tx.getSessionId() == null) { 138 try { 139 response = getClient().post(URI.create(baseUrl + FcrepoConstants.TRANSACTION), is, contentType); 140 } catch (FcrepoOperationFailedException ex) { 141 LOGGER.debug("HTTP Operation failed: ", ex); 142 throw new CannotCreateTransactionException("Could not create fcrepo transaction"); 143 } 144 145 if (response != null && response.getLocation() != null) { 146 tx.setSessionId(response.getLocation().toString().substring(baseUrl.length() + 1)); 147 } else { 148 throw new CannotCreateTransactionException("Invalid response while creating transaction"); 149 } 150 } 151 } 152 153 @Override 154 protected void doCommit(final DefaultTransactionStatus status) { 155 final FcrepoTransactionObject tx = (FcrepoTransactionObject)status.getTransaction(); 156 final InputStream is = null; 157 final String contentType = null; 158 159 try { 160 getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + FcrepoConstants.COMMIT), is, contentType); 161 } catch (FcrepoOperationFailedException ex) { 162 LOGGER.debug("Transaction commit failed: ", ex); 163 throw new TransactionSystemException("Could not commit fcrepo transaction"); 164 } finally { 165 tx.setSessionId(null); 166 } 167 } 168 169 @Override 170 protected void doRollback(final DefaultTransactionStatus status) { 171 final FcrepoTransactionObject tx = (FcrepoTransactionObject)status.getTransaction(); 172 173 try { 174 getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + FcrepoConstants.ROLLBACK), null, null); 175 } catch (FcrepoOperationFailedException ex) { 176 LOGGER.debug("Transaction rollback failed: ", ex); 177 throw new TransactionSystemException("Could not rollback fcrepo transaction"); 178 } finally { 179 tx.setSessionId(null); 180 } 181 } 182 183 @Override 184 protected Object doGetTransaction() { 185 return new FcrepoTransactionObject(); 186 } 187 188 private FcrepoClient getClient() { 189 final Boolean throwExceptionOnFailure = true; 190 191 if (client == null) { 192 client = new FcrepoClient( 193 authUsername, 194 authPassword, 195 authHost, 196 throwExceptionOnFailure); 197 } 198 return client; 199 } 200}