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.junit.Assert.assertEquals;
019import static org.junit.Assert.assertFalse;
020import static org.junit.Assert.assertNull;
021import static org.junit.Assert.assertTrue;
022import static org.mockito.Matchers.any;
023import static org.mockito.Matchers.anyString;
024import static org.mockito.Matchers.eq;
025import static org.mockito.Mockito.when;
026
027import java.io.InputStream;
028import java.net.URI;
029
030import org.fcrepo.client.FcrepoClient;
031import org.fcrepo.client.FcrepoOperationFailedException;
032import org.fcrepo.client.FcrepoResponse;
033import org.junit.Test;
034import org.junit.runner.RunWith;
035import org.mockito.Mock;
036import org.mockito.runners.MockitoJUnitRunner;
037import org.springframework.transaction.CannotCreateTransactionException;
038import org.springframework.transaction.TransactionDefinition;
039import org.springframework.transaction.TransactionSystemException;
040import org.springframework.transaction.support.DefaultTransactionDefinition;
041import org.springframework.transaction.support.DefaultTransactionStatus;
042import org.springframework.transaction.support.TransactionTemplate;
043
044/**
045 * @author Aaron Coburn
046 */
047@RunWith(MockitoJUnitRunner.class)
048public class FcrepoTransactionManagerTest {
049
050    @Mock
051    private FcrepoClient mockClient;
052
053    @Test
054    public void testProperties() {
055        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
056        final String baseUrl = "http://localhost:8080/rest";
057        final String authUsername = "foo";
058        final String authPassword = "bar";
059        final String authHost = "baz";
060        final String transactionId = "1234567890";
061
062        assertNull(txMgr.getAuthUsername());
063        assertNull(txMgr.getAuthPassword());
064        assertNull(txMgr.getAuthHost());
065        assertNull(txMgr.getBaseUrl());
066
067        txMgr.setBaseUrl(baseUrl);
068        txMgr.setAuthUsername(authUsername);
069        txMgr.setAuthPassword(authPassword);
070        txMgr.setAuthHost(authHost);
071
072        assertEquals(baseUrl, txMgr.getBaseUrl());
073        assertEquals(authUsername, txMgr.getAuthUsername());
074        assertEquals(authPassword, txMgr.getAuthPassword());
075        assertEquals(authHost, txMgr.getAuthHost());
076    }
077
078    @Test
079    public void testTransactionCommit() throws FcrepoOperationFailedException {
080        final String baseUrl = "http://localhost:8080/rest";
081        final String tx = "tx:1234567890";
082        final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT);
083        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
084        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
085        txMgr.setBaseUrl(baseUrl);
086        TestUtils.setField(txMgr, "client", mockClient);
087
088        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
089        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
090                TransactionDefinition.PROPAGATION_REQUIRED);
091
092        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
093        transactionTemplate.afterPropertiesSet();
094
095        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
096                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
097        when(mockClient.post(eq(commitUri), any(InputStream.class), anyString())).thenReturn(
098                new FcrepoResponse(commitUri, 201, null, null, null));
099
100        DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
101        FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction();
102
103        assertEquals(tx, txObj.getSessionId());
104        assertFalse(status.isCompleted());
105
106        status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
107
108        txMgr.commit(status);
109
110        txObj = (FcrepoTransactionObject)status.getTransaction();
111
112        assertNull(txObj.getSessionId());
113        assertTrue(status.isCompleted());
114    }
115
116    @Test
117    public void testTransactionRollback() throws FcrepoOperationFailedException {
118        final String baseUrl = "http://localhost:8080/rest";
119        final String tx = "tx:1234567890";
120        final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT);
121        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
122        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
123        txMgr.setBaseUrl(baseUrl);
124        TestUtils.setField(txMgr, "client", mockClient);
125
126        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
127        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
128                TransactionDefinition.PROPAGATION_REQUIRED);
129
130        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
131        transactionTemplate.afterPropertiesSet();
132
133        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
134                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
135        when(mockClient.post(eq(commitUri), any(InputStream.class), anyString())).thenReturn(
136                new FcrepoResponse(commitUri, 201, null, null, null));
137
138        DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
139        FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction();
140
141        assertEquals(tx, txObj.getSessionId());
142        assertFalse(status.isCompleted());
143
144        status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
145
146        txMgr.rollback(status);
147
148        txObj = (FcrepoTransactionObject)status.getTransaction();
149
150        assertNull(txObj.getSessionId());
151        assertTrue(status.isCompleted());
152    }
153
154    @Test (expected = CannotCreateTransactionException.class)
155    public void testTransactionBeginError() throws FcrepoOperationFailedException {
156        final String baseUrl = "http://localhost:8080/rest";
157        final String tx = "tx:1234567890";
158        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
159        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
160        txMgr.setBaseUrl(baseUrl);
161        TestUtils.setField(txMgr, "client", mockClient);
162
163        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
164        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
165                TransactionDefinition.PROPAGATION_REQUIRED);
166
167        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
168        transactionTemplate.afterPropertiesSet();
169
170        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenThrow(
171                new FcrepoOperationFailedException(beginUri, 400, "Bad Request"));
172
173        txMgr.getTransaction(txDef);
174    }
175
176    @Test (expected = CannotCreateTransactionException.class)
177    public void testTransactionBeginNoLocationError() throws FcrepoOperationFailedException {
178        final String baseUrl = "http://localhost:8080/rest";
179        final String tx = "tx:1234567890";
180        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
181        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
182        txMgr.setBaseUrl(baseUrl);
183        TestUtils.setField(txMgr, "client", mockClient);
184
185        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
186        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
187                TransactionDefinition.PROPAGATION_REQUIRED);
188
189        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
190        transactionTemplate.afterPropertiesSet();
191
192        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
193                new FcrepoResponse(beginUri, 201, null, null, null));
194
195        txMgr.getTransaction(txDef);
196    }
197
198    @Test (expected = CannotCreateTransactionException.class)
199    public void testTransactionNullResponseError() throws FcrepoOperationFailedException {
200        final String baseUrl = "http://localhost:8080/rest";
201        final String tx = "tx:1234567890";
202        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
203        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
204        txMgr.setBaseUrl(baseUrl);
205        TestUtils.setField(txMgr, "client", mockClient);
206
207        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
208        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
209                TransactionDefinition.PROPAGATION_REQUIRED);
210
211        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
212        transactionTemplate.afterPropertiesSet();
213
214        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(null);
215
216        txMgr.getTransaction(txDef);
217    }
218
219    @Test (expected = TransactionSystemException.class)
220    public void testTransactionCommitError() throws FcrepoOperationFailedException {
221        final String baseUrl = "http://localhost:8080/rest";
222        final String tx = "tx:1234567890";
223        final URI commitUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.COMMIT);
224        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
225        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
226        txMgr.setBaseUrl(baseUrl);
227        TestUtils.setField(txMgr, "client", mockClient);
228
229        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
230        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
231                TransactionDefinition.PROPAGATION_REQUIRED);
232
233        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
234        transactionTemplate.afterPropertiesSet();
235
236        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
237                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
238        when(mockClient.post(eq(commitUri), any(InputStream.class), anyString())).thenThrow(
239                new FcrepoOperationFailedException(commitUri, 400, "Bad Request"));
240
241        DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
242
243        final FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction();
244        assertEquals(tx, txObj.getSessionId());
245        assertFalse(status.isCompleted());
246
247        status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
248        txMgr.commit(status);
249    }
250
251    @Test (expected = TransactionSystemException.class)
252    public void testTransactionRollbackError() throws FcrepoOperationFailedException {
253        final String baseUrl = "http://localhost:8080/rest";
254        final String tx = "tx:1234567890";
255        final URI rollbackUri = URI.create(baseUrl + "/" + tx + FcrepoConstants.ROLLBACK);
256        final URI beginUri = URI.create(baseUrl + FcrepoConstants.TRANSACTION);
257        final FcrepoTransactionManager txMgr = new FcrepoTransactionManager();
258        txMgr.setBaseUrl(baseUrl);
259        TestUtils.setField(txMgr, "client", mockClient);
260
261        final TransactionTemplate transactionTemplate = new TransactionTemplate(txMgr);
262        final DefaultTransactionDefinition txDef = new DefaultTransactionDefinition(
263                TransactionDefinition.PROPAGATION_REQUIRED);
264
265        transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
266        transactionTemplate.afterPropertiesSet();
267
268        when(mockClient.post(eq(beginUri), any(InputStream.class), anyString())).thenReturn(
269                new FcrepoResponse(beginUri, 201, null, URI.create(baseUrl + "/" + tx), null));
270        when(mockClient.post(eq(rollbackUri), any(InputStream.class), anyString())).thenThrow(
271                new FcrepoOperationFailedException(rollbackUri, 400, "Bad Request"));
272
273        DefaultTransactionStatus status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
274
275        final FcrepoTransactionObject txObj = (FcrepoTransactionObject)status.getTransaction();
276        assertEquals(tx, txObj.getSessionId());
277        assertFalse(status.isCompleted());
278
279        status = (DefaultTransactionStatus)txMgr.getTransaction(txDef);
280        txMgr.rollback(status);
281    }
282}