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.fcrepo.client.FcrepoClient; 024import org.fcrepo.client.FcrepoOperationFailedException; 025import org.fcrepo.client.FcrepoResponse; 026import org.slf4j.Logger; 027import org.springframework.transaction.CannotCreateTransactionException; 028import org.springframework.transaction.TransactionDefinition; 029import org.springframework.transaction.TransactionSystemException; 030import org.springframework.transaction.support.AbstractPlatformTransactionManager; 031import org.springframework.transaction.support.DefaultTransactionStatus; 032 033/** 034 * A Transaction Manager for interacting with fedora-based transactions 035 * 036 * @author Aaron Coburn 037 * @since Feb 16, 2015 038 */ 039public class FcrepoTransactionManager extends AbstractPlatformTransactionManager { 040 041 private FcrepoClient client; 042 043 private String baseUrl; 044 045 private String authUsername; 046 047 private String authPassword; 048 049 private String authHost; 050 051 private static final Logger LOGGER = getLogger(FcrepoTransactionManager.class); 052 053 /** 054 * Create a FcrepoTransactionManager 055 */ 056 public FcrepoTransactionManager() { 057 super(); 058 setNestedTransactionAllowed(false); 059 } 060 061 /** 062 * Set the baseUrl for the transaction manager. 063 * 064 * @param baseUrl the fcrepo base url 065 */ 066 public void setBaseUrl(final String baseUrl) { 067 this.baseUrl = baseUrl; 068 } 069 070 /** 071 * Get the base url for the transaction manager. 072 * 073 * @return the fcrepo base url 074 */ 075 public String getBaseUrl() { 076 return baseUrl; 077 } 078 079 /** 080 * Set the authUsername for the transaction manager. 081 * 082 * @param authUsername the username for authentication 083 */ 084 public void setAuthUsername(final String authUsername) { 085 this.authUsername = authUsername; 086 } 087 088 /** 089 * Get the authUsername for the transaction manager. 090 * 091 * @return the username for authentication 092 */ 093 public String getAuthUsername() { 094 return authUsername; 095 } 096 097 /** 098 * Set the authPassword for the transaction manager. 099 * 100 * @param authPassword the password used for authentication 101 */ 102 public void setAuthPassword(final String authPassword) { 103 this.authPassword = authPassword; 104 } 105 106 /** 107 * Get the authPassword for the transaction manager. 108 * 109 * @return the password used for authentication 110 */ 111 public String getAuthPassword() { 112 return authPassword; 113 } 114 115 /** 116 * Set the authHost for the transaction manager. 117 * 118 * @param authHost the host realm used for authentication 119 */ 120 public void setAuthHost(final String authHost) { 121 this.authHost = authHost; 122 } 123 124 /** 125 * Get the authHost for the transaction manager. 126 * 127 * @return the host realm used for authentication 128 */ 129 public String getAuthHost() { 130 return authHost; 131 } 132 133 @Override 134 protected void doBegin(final Object transaction, final TransactionDefinition definition) { 135 final FcrepoResponse response; 136 final InputStream is = null; 137 final String contentType = null; 138 final FcrepoTransactionObject tx = (FcrepoTransactionObject)transaction; 139 140 if (tx.getSessionId() == null) { 141 try { 142 response = getClient().post(URI.create(baseUrl + FcrepoConstants.TRANSACTION), is, contentType); 143 } catch (FcrepoOperationFailedException ex) { 144 LOGGER.debug("HTTP Operation failed: ", ex); 145 throw new CannotCreateTransactionException("Could not create fcrepo transaction"); 146 } 147 148 if (response != null && response.getLocation() != null) { 149 tx.setSessionId(response.getLocation().toString().substring(baseUrl.length() + 1)); 150 } else { 151 throw new CannotCreateTransactionException("Invalid response while creating transaction"); 152 } 153 } 154 } 155 156 @Override 157 protected void doCommit(final DefaultTransactionStatus status) { 158 final FcrepoTransactionObject tx = (FcrepoTransactionObject)status.getTransaction(); 159 final InputStream is = null; 160 final String contentType = null; 161 162 try { 163 getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + FcrepoConstants.COMMIT), is, contentType); 164 } catch (FcrepoOperationFailedException ex) { 165 LOGGER.debug("Transaction commit failed: ", ex); 166 throw new TransactionSystemException("Could not commit fcrepo transaction"); 167 } finally { 168 tx.setSessionId(null); 169 } 170 } 171 172 @Override 173 protected void doRollback(final DefaultTransactionStatus status) { 174 final FcrepoTransactionObject tx = (FcrepoTransactionObject)status.getTransaction(); 175 176 try { 177 getClient().post(URI.create(baseUrl + "/" + tx.getSessionId() + FcrepoConstants.ROLLBACK), null, null); 178 } catch (FcrepoOperationFailedException ex) { 179 LOGGER.debug("Transaction rollback failed: ", ex); 180 throw new TransactionSystemException("Could not rollback fcrepo transaction"); 181 } finally { 182 tx.setSessionId(null); 183 } 184 } 185 186 @Override 187 protected Object doGetTransaction() { 188 return new FcrepoTransactionObject(); 189 } 190 191 private FcrepoClient getClient() { 192 final Boolean throwExceptionOnFailure = true; 193 194 if (client == null) { 195 client = new FcrepoClient( 196 authUsername, 197 authPassword, 198 authHost, 199 throwExceptionOnFailure); 200 } 201 return client; 202 } 203}