001/* 002 * Licensed to DuraSpace under one or more contributor license agreements. 003 * See the NOTICE file distributed with this work for additional information 004 * regarding copyright ownership. 005 * 006 * DuraSpace licenses this file to you under the Apache License, 007 * Version 2.0 (the "License"); you may not use this file except in 008 * compliance with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.fcrepo.camel; 019 020import static java.util.Collections.emptyMap; 021import static java.util.Collections.singletonList; 022import static java.util.Collections.singletonMap; 023import static org.junit.Assert.assertEquals; 024import static org.junit.Assert.assertFalse; 025import static org.junit.Assert.assertNull; 026import static org.junit.Assert.assertTrue; 027import static org.mockito.Matchers.any; 028import static org.mockito.Matchers.eq; 029import static org.mockito.Mockito.when; 030 031import java.io.InputStream; 032import java.net.URI; 033import java.util.List; 034 035import org.fcrepo.client.FcrepoClient; 036import org.fcrepo.client.FcrepoOperationFailedException; 037import org.fcrepo.client.FcrepoResponse; 038import org.fcrepo.client.GetBuilder; 039import org.fcrepo.client.HeadBuilder; 040import org.fcrepo.client.PostBuilder; 041import org.junit.Before; 042import org.junit.Test; 043import org.junit.runner.RunWith; 044import org.mockito.Mock; 045import org.mockito.runners.MockitoJUnitRunner; 046import org.springframework.transaction.CannotCreateTransactionException; 047import org.springframework.transaction.TransactionDefinition; 048import org.springframework.transaction.TransactionSystemException; 049import org.springframework.transaction.support.DefaultTransactionDefinition; 050import org.springframework.transaction.support.DefaultTransactionStatus; 051import org.springframework.transaction.support.TransactionTemplate; 052 053/** 054 * @author Aaron Coburn 055 */ 056@RunWith(MockitoJUnitRunner.class) 057public class FcrepoTransactionManagerTest { 058 059 @Mock 060 private FcrepoClient mockClient; 061 062 @Mock 063 private PostBuilder mockPostBuilder, mockPostBuilder2; 064 065 @Mock 066 private GetBuilder mockGetBuilder; 067 068 @Mock 069 private HeadBuilder mockHeadBuilder; 070 071 @Before 072 @SuppressWarnings("unchecked") 073 public void setUp() throws Exception { 074 when(mockClient.head(any(URI.class))).thenReturn(mockHeadBuilder); 075 when(mockClient.get(any(URI.class))).thenReturn(mockGetBuilder); 076 when(mockGetBuilder.accept(any(String.class))).thenReturn(mockGetBuilder); 077 when(mockGetBuilder.preferMinimal()).thenReturn(mockGetBuilder); 078 when(mockGetBuilder.preferRepresentation(any(List.class), any(List.class))).thenReturn(mockGetBuilder); 079 when(mockClient.post(any(URI.class))).thenReturn(mockPostBuilder); 080 when(mockPostBuilder.body(any(InputStream.class), any(String.class))).thenReturn(mockPostBuilder); 081 when(mockPostBuilder2.body(any(InputStream.class), any(String.class))).thenReturn(mockPostBuilder2); 082 } 083 084 @Test 085 public void testProperties() { 086 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 087 final String baseUrl = "http://localhost:8080/rest"; 088 final String authUsername = "foo"; 089 final String authPassword = "bar"; 090 final String authHost = "baz"; 091 final String transactionId = "1234567890"; 092 093 assertNull(txMgr.getAuthUsername()); 094 assertNull(txMgr.getAuthPassword()); 095 assertNull(txMgr.getAuthHost()); 096 assertNull(txMgr.getBaseUrl()); 097 098 txMgr.setBaseUrl(baseUrl); 099 txMgr.setAuthUsername(authUsername); 100 txMgr.setAuthPassword(authPassword); 101 txMgr.setAuthHost(authHost); 102 103 assertEquals(baseUrl, txMgr.getBaseUrl()); 104 assertEquals(authUsername, txMgr.getAuthUsername()); 105 assertEquals(authPassword, txMgr.getAuthPassword()); 106 assertEquals(authHost, txMgr.getAuthHost()); 107 } 108 109 @Test 110 public void testTransactionCommit() throws FcrepoOperationFailedException { 111 final String baseUrl = "http://localhost:8080/rest"; 112 final String tx = "tx:1234567890"; 113 final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT); 114 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 115 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 116 txMgr.setBaseUrl(baseUrl); 117 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 118 119 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 120 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 121 TransactionDefinition.PROPAGATION_REQUIRED); 122 123 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 124 transactionTemplate.afterPropertiesSet(); 125 126 when(mockClient.post(eq(beginUri))).thenReturn(mockPostBuilder); 127 when(mockClient.post(eq(commitUri))).thenReturn(mockPostBuilder2); 128 when(mockPostBuilder.perform()).thenReturn( 129 new FcrepoResponse(beginUri, 201, singletonMap("Location", singletonList(baseUrl + "/" + tx)), null)); 130 when(mockPostBuilder2.perform()).thenReturn( 131 new FcrepoResponse(commitUri, 201, emptyMap(), null)); 132 133 DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 134 FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction(); 135 136 assertEquals(tx, txObj.getSessionId()); 137 assertFalse(status.isCompleted()); 138 139 status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 140 141 txMgr.commit(status); 142 143 txObj = (FcrepoTransactionObject)status.getTransaction(); 144 145 assertNull(txObj.getSessionId()); 146 assertTrue(status.isCompleted()); 147 } 148 149 @Test 150 public void testTransactionRollback() throws FcrepoOperationFailedException { 151 final String baseUrl = "http://localhost:8080/rest"; 152 final String tx = "tx:1234567890"; 153 final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT); 154 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 155 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 156 txMgr.setBaseUrl(baseUrl); 157 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 158 159 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 160 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 161 TransactionDefinition.PROPAGATION_REQUIRED); 162 163 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 164 transactionTemplate.afterPropertiesSet(); 165 166 when(mockClient.post(eq(beginUri))).thenReturn(mockPostBuilder); 167 when(mockClient.post(eq(commitUri))).thenReturn(mockPostBuilder2); 168 when(mockPostBuilder.perform()).thenReturn( 169 new FcrepoResponse(beginUri, 201, singletonMap("Location", singletonList(baseUrl + "/" + tx)), null)); 170 when(mockPostBuilder2.perform()).thenReturn( 171 new FcrepoResponse(commitUri, 201, emptyMap(), null)); 172 173 DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 174 FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction(); 175 176 assertEquals(tx, txObj.getSessionId()); 177 assertFalse(status.isCompleted()); 178 179 status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 180 181 txMgr.rollback(status); 182 183 txObj = (FcrepoTransactionObject)status.getTransaction(); 184 185 assertNull(txObj.getSessionId()); 186 assertTrue(status.isCompleted()); 187 } 188 189 @Test (expected = CannotCreateTransactionException.class) 190 public void testTransactionBeginError() throws FcrepoOperationFailedException { 191 final String baseUrl = "http://localhost:8080/rest"; 192 final String tx = "tx:1234567890"; 193 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 194 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 195 txMgr.setBaseUrl(baseUrl); 196 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 197 198 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 199 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 200 TransactionDefinition.PROPAGATION_REQUIRED); 201 202 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 203 transactionTemplate.afterPropertiesSet(); 204 205 when(mockPostBuilder.perform()).thenThrow( 206 new FcrepoOperationFailedException(beginUri, 400, "Bad Request")); 207 208 txMgr.getTransaction(txDef); 209 } 210 211 @Test (expected = CannotCreateTransactionException.class) 212 public void testTransactionBeginNoLocationError() throws FcrepoOperationFailedException { 213 final String baseUrl = "http://localhost:8080/rest"; 214 final String tx = "tx:1234567890"; 215 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 216 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 217 txMgr.setBaseUrl(baseUrl); 218 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 219 220 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 221 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 222 TransactionDefinition.PROPAGATION_REQUIRED); 223 224 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 225 transactionTemplate.afterPropertiesSet(); 226 227 when(mockPostBuilder.perform()).thenReturn( 228 new FcrepoResponse(beginUri, 201, emptyMap(), null)); 229 230 txMgr.getTransaction(txDef); 231 } 232 233 @Test (expected = CannotCreateTransactionException.class) 234 public void testTransactionNullResponseError() throws FcrepoOperationFailedException { 235 final String baseUrl = "http://localhost:8080/rest"; 236 final String tx = "tx:1234567890"; 237 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 238 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 239 txMgr.setBaseUrl(baseUrl); 240 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 241 242 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 243 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 244 TransactionDefinition.PROPAGATION_REQUIRED); 245 246 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 247 transactionTemplate.afterPropertiesSet(); 248 249 when(mockPostBuilder.perform()).thenReturn(null); 250 251 txMgr.getTransaction(txDef); 252 } 253 254 @Test (expected = TransactionSystemException.class) 255 public void testTransactionCommitError() throws FcrepoOperationFailedException { 256 final String baseUrl = "http://localhost:8080/rest"; 257 final String tx = "tx:1234567890"; 258 final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT); 259 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 260 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 261 txMgr.setBaseUrl(baseUrl); 262 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 263 264 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 265 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 266 TransactionDefinition.PROPAGATION_REQUIRED); 267 268 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 269 transactionTemplate.afterPropertiesSet(); 270 271 when(mockClient.post(eq(beginUri))).thenReturn(mockPostBuilder); 272 when(mockClient.post(eq(commitUri))).thenReturn(mockPostBuilder2); 273 when(mockPostBuilder.perform()).thenReturn( 274 new FcrepoResponse(beginUri, 201, singletonMap("Location", singletonList(baseUrl + "/" + tx)), null)); 275 when(mockPostBuilder2.perform()).thenThrow( 276 new FcrepoOperationFailedException(commitUri, 400, "Bad Request")); 277 278 DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 279 280 final FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction(); 281 assertEquals(tx, txObj.getSessionId()); 282 assertFalse(status.isCompleted()); 283 284 status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 285 txMgr.commit(status); 286 } 287 288 @Test (expected = TransactionSystemException.class) 289 public void testTransactionRollbackError() throws FcrepoOperationFailedException { 290 final String baseUrl = "http://localhost:8080/rest"; 291 final String tx = "tx:1234567890"; 292 final URI rollbackUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.ROLLBACK); 293 final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION); 294 final FcrepoTransactionManager txMgr = new FcrepoTransactionManager(); 295 txMgr.setBaseUrl(baseUrl); 296 TestUtils.setField(txMgr, "fcrepoClient", mockClient); 297 298 final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr); 299 final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition( 300 TransactionDefinition.PROPAGATION_REQUIRED); 301 302 transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); 303 transactionTemplate.afterPropertiesSet(); 304 305 when(mockClient.post(eq(beginUri))).thenReturn(mockPostBuilder); 306 when(mockClient.post(eq(rollbackUri))).thenReturn(mockPostBuilder2); 307 when(mockPostBuilder.perform()).thenReturn( 308 new FcrepoResponse(beginUri, 201, singletonMap("Location", singletonList(baseUrl + "/" + tx)), null)); 309 when(mockPostBuilder2.perform()).thenThrow( 310 new FcrepoOperationFailedException(rollbackUri, 400, "Bad Request")); 311 312 DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 313 314 final FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction(); 315 assertEquals(tx, txObj.getSessionId()); 316 assertFalse(status.isCompleted()); 317 318 status = (DefaultTransactionStatus)txMgr.getTransaction(txDef); 319 txMgr.rollback(status); 320 } 321}