Skip to content

Commit dd9c3ed

Browse files
committed
DATACOUCH-17 - Make ops sync & map exceptions
1 parent 2eedc4b commit dd9c3ed

File tree

5 files changed

+135
-18
lines changed

5 files changed

+135
-18
lines changed

src/main/java/org/springframework/data/couchbase/core/BucketCallback.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,12 @@
1616

1717
package org.springframework.data.couchbase.core;
1818

19+
import java.util.concurrent.ExecutionException;
20+
import java.util.concurrent.TimeoutException;
21+
1922
/**
2023
* @author Michael Nitschinger
2124
*/
2225
public interface BucketCallback<T> {
23-
T doInBucket();
26+
T doInBucket() throws TimeoutException, ExecutionException, InterruptedException;
2427
}

src/main/java/org/springframework/data/couchbase/core/CouchbaseExceptionTranslator.java

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,21 @@
1616

1717
package org.springframework.data.couchbase.core;
1818

19+
import com.couchbase.client.protocol.views.InvalidViewException;
20+
import com.couchbase.client.protocol.views.ViewException;
1921
import org.springframework.dao.DataAccessException;
2022
import org.springframework.dao.DataAccessResourceFailureException;
2123
import org.springframework.dao.DataIntegrityViolationException;
24+
import org.springframework.dao.InvalidDataAccessResourceUsageException;
2225
import org.springframework.dao.support.PersistenceExceptionTranslator;
2326

2427
import com.couchbase.client.ObservedException;
2528
import com.couchbase.client.ObservedModifiedException;
2629
import com.couchbase.client.ObservedTimeoutException;
2730
import com.couchbase.client.vbucket.ConnectionException;
2831

29-
import java.io.IOException;
32+
import java.util.concurrent.CancellationException;
33+
3034

3135
/**
3236
* Simple {@link PersistenceExceptionTranslator} for Couchbase.
@@ -35,6 +39,8 @@
3539
* {@code org.springframework.dao} hierarchy. Return {@literal null} if no translation
3640
* is appropriate: any other exception may have resulted from user code, and should not
3741
* be translated.
42+
*
43+
* @author Michael Nitschinger
3844
*/
3945
public class CouchbaseExceptionTranslator implements PersistenceExceptionTranslator {
4046

@@ -45,7 +51,8 @@ public class CouchbaseExceptionTranslator implements PersistenceExceptionTransla
4551
* @return the translated exception or null.
4652
*/
4753
@Override
48-
public final DataAccessException translateExceptionIfPossible(RuntimeException ex) {
54+
public final DataAccessException translateExceptionIfPossible(final RuntimeException ex) {
55+
4956
if (ex instanceof ConnectionException) {
5057
return new DataAccessResourceFailureException(ex.getMessage(), ex);
5158
}
@@ -55,6 +62,14 @@ public final DataAccessException translateExceptionIfPossible(RuntimeException e
5562
|| ex instanceof ObservedModifiedException) {
5663
return new DataIntegrityViolationException(ex.getMessage(), ex);
5764
}
65+
66+
if (ex instanceof CancellationException) {
67+
throw new OperationCancellationException(ex.getMessage(), ex);
68+
}
69+
70+
if (ex instanceof InvalidViewException) {
71+
throw new InvalidDataAccessResourceUsageException(ex.getMessage(), ex);
72+
}
5873

5974
return null;
6075
}

src/main/java/org/springframework/data/couchbase/core/CouchbaseTemplate.java

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,16 @@
1717
package org.springframework.data.couchbase.core;
1818

1919
import java.util.*;
20+
import java.util.concurrent.ExecutionException;
21+
import java.util.concurrent.TimeoutException;
2022

2123
import com.couchbase.client.protocol.views.Query;
2224
import com.couchbase.client.protocol.views.View;
2325
import com.couchbase.client.protocol.views.ViewResponse;
2426
import com.couchbase.client.protocol.views.ViewRow;
2527
import net.spy.memcached.internal.OperationFuture;
2628

29+
import org.springframework.dao.QueryTimeoutException;
2730
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
2831
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
2932
import org.springframework.data.couchbase.core.convert.translation.JacksonTranslationService;
@@ -91,11 +94,10 @@ public final void insert(final Object objectToSave) {
9194
final CouchbaseDocument converted = new CouchbaseDocument();
9295
couchbaseConverter.write(objectToSave, converted);
9396

94-
execute(new BucketCallback<OperationFuture<Boolean>>() {
97+
execute(new BucketCallback<Boolean>() {
9598
@Override
96-
public OperationFuture<Boolean> doInBucket() {
97-
return client.add(
98-
converted.getId(), converted.getExpiration(), translateEncode(converted));
99+
public Boolean doInBucket() throws InterruptedException, ExecutionException {
100+
return client.add(converted.getId(), converted.getExpiration(), translateEncode(converted)).get();
99101
}
100102
});
101103
}
@@ -113,11 +115,10 @@ public void save(final Object objectToSave) {
113115
final CouchbaseDocument converted = new CouchbaseDocument();
114116
couchbaseConverter.write(objectToSave, converted);
115117

116-
execute(new BucketCallback<OperationFuture<Boolean>>() {
118+
execute(new BucketCallback<Boolean>() {
117119
@Override
118-
public OperationFuture<Boolean> doInBucket() {
119-
return client.set(
120-
converted.getId(), converted.getExpiration(), translateEncode(converted));
120+
public Boolean doInBucket() throws InterruptedException, ExecutionException {
121+
return client.set(converted.getId(), converted.getExpiration(), translateEncode(converted)).get();
121122
}
122123
});
123124
}
@@ -135,11 +136,10 @@ public void update(final Object objectToSave) {
135136
final CouchbaseDocument converted = new CouchbaseDocument();
136137
couchbaseConverter.write(objectToSave, converted);
137138

138-
execute(new BucketCallback<OperationFuture<Boolean>>() {
139+
execute(new BucketCallback<Boolean>() {
139140
@Override
140-
public OperationFuture<Boolean> doInBucket() {
141-
return client.replace(
142-
converted.getId(), converted.getExpiration(), translateEncode(converted));
141+
public Boolean doInBucket() throws InterruptedException, ExecutionException {
142+
return client.replace(converted.getId(), converted.getExpiration(), translateEncode(converted)).get();
143143
}
144144
});
145145

@@ -208,10 +208,10 @@ public void remove(final Object objectToRemove) {
208208
ensureNotIterable(objectToRemove);
209209

210210
if (objectToRemove instanceof String) {
211-
execute(new BucketCallback<OperationFuture<Boolean>>() {
211+
execute(new BucketCallback<Boolean>() {
212212
@Override
213-
public OperationFuture<Boolean> doInBucket() {
214-
return client.delete((String) objectToRemove);
213+
public Boolean doInBucket() throws InterruptedException, ExecutionException {
214+
return client.delete((String) objectToRemove).get();
215215
}
216216
});
217217
return;
@@ -235,11 +235,18 @@ public void remove(final Collection<? extends Object> batchToRemove) {
235235
}
236236
}
237237

238+
@Override
238239
public <T> T execute(final BucketCallback<T> action) {
239240
try {
240241
return action.doInBucket();
241242
} catch (RuntimeException e) {
242243
throw potentiallyConvertRuntimeException(e);
244+
} catch (TimeoutException e) {
245+
throw new QueryTimeoutException(e.getMessage(), e);
246+
} catch (InterruptedException e) {
247+
throw new OperationInterruptedException(e.getMessage(), e);
248+
} catch (ExecutionException e) {
249+
throw new OperationInterruptedException(e.getMessage(), e);
243250
}
244251
}
245252

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.core;
18+
19+
import org.springframework.dao.TransientDataAccessException;
20+
21+
/**
22+
* Data Access Exception that identifies Operations cancelled while being
23+
* processed.
24+
*
25+
* @author Michael Nitschinger
26+
*/
27+
public class OperationCancellationException extends TransientDataAccessException {
28+
29+
/**
30+
* Constructor for OperationCancellationException.
31+
* @param msg the detail message
32+
*/
33+
public OperationCancellationException(final String msg) {
34+
super(msg);
35+
}
36+
37+
/**
38+
* Constructor for OperationCancellationException.
39+
* @param msg the detail message
40+
* @param cause the root cause from the data access API in use
41+
*/
42+
public OperationCancellationException(final String msg, final Throwable cause) {
43+
super(msg, cause);
44+
}
45+
46+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
/*
2+
* Copyright 2013 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.data.couchbase.core;
18+
19+
import org.springframework.dao.TransientDataAccessException;
20+
21+
/**
22+
* Data Access Exception that identifies Operations interrupted while being
23+
* processed.
24+
*
25+
* @author Michael Nitschinger
26+
*/
27+
public class OperationInterruptedException extends TransientDataAccessException {
28+
29+
/**
30+
* Constructor for OperationInterruptedException.
31+
* @param msg the detail message
32+
*/
33+
public OperationInterruptedException(final String msg) {
34+
super(msg);
35+
}
36+
37+
/**
38+
* Constructor for OperationInterruptedException.
39+
* @param msg the detail message
40+
* @param cause the root cause from the data access API in use
41+
*/
42+
public OperationInterruptedException(final String msg, final Throwable cause) {
43+
super(msg, cause);
44+
}
45+
46+
}

0 commit comments

Comments
 (0)