1 | /* |
2 | * Copyright 2006-2007 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.batch.retry.callback; |
18 | |
19 | import org.springframework.batch.retry.RecoveryCallback; |
20 | import org.springframework.batch.retry.RetryCallback; |
21 | import org.springframework.batch.retry.RetryContext; |
22 | import org.springframework.batch.retry.RetryPolicy; |
23 | import org.springframework.batch.retry.policy.RecoveryCallbackRetryPolicy; |
24 | |
25 | /** |
26 | * A {@link RetryCallback} that knows about and caches an item, and attempts to |
27 | * process it using a delegate {@link RetryCallback}. Used by the |
28 | * {@link RecoveryCallbackRetryPolicy} to enable stateful retry of the |
29 | * processing. |
30 | * |
31 | * @author Dave Syer |
32 | * |
33 | * @see RecoveryCallbackRetryPolicy |
34 | * @see RetryPolicy#handleRetryExhausted(RetryContext) |
35 | * |
36 | */ |
37 | public class RecoveryRetryCallback implements RetryCallback { |
38 | |
39 | private final Object item; |
40 | |
41 | private final RetryCallback callback; |
42 | |
43 | private RecoveryCallback recoverer; |
44 | |
45 | private final Object key; |
46 | |
47 | private boolean forceRefresh = false; |
48 | |
49 | /** |
50 | * Constructor with mandatory properties. The key will be set to the item. |
51 | * |
52 | * @param item the item to process |
53 | * @param callback the delegate to use to process it |
54 | */ |
55 | public RecoveryRetryCallback(Object item, RetryCallback callback) { |
56 | super(); |
57 | this.item = item; |
58 | this.callback = callback; |
59 | this.key = item; |
60 | } |
61 | |
62 | /** |
63 | * Constructor with mandatory properties. |
64 | * |
65 | * @param item the item to process |
66 | * @param callback the delegate to use to process it |
67 | */ |
68 | public RecoveryRetryCallback(Object item, RetryCallback callback, Object key) { |
69 | super(); |
70 | this.item = item; |
71 | this.callback = callback; |
72 | this.key = key; |
73 | } |
74 | |
75 | /** |
76 | * Public getter for the key. This will be used to identify the item being |
77 | * processed, to see if it has previously failed. |
78 | * @return the key |
79 | */ |
80 | public Object getKey() { |
81 | return key; |
82 | } |
83 | |
84 | /** |
85 | * Setter for injecting optional recovery handler. |
86 | * |
87 | * @param recoverer |
88 | */ |
89 | public void setRecoveryCallback(RecoveryCallback recoverer) { |
90 | this.recoverer = recoverer; |
91 | } |
92 | |
93 | /** |
94 | * Public setter for a flag signalling to clients of this callback that the |
95 | * processing is not a retry. It is always safe to leave this set to the |
96 | * default value (false), but in some cases it is possible to determine by |
97 | * examining the input data whether a failure has never been encountered |
98 | * (e.g. a message header saying that the message has never been consumed). |
99 | * Clients who have this information can avoid a cache query in such cases |
100 | * by setting the flag to true. |
101 | * |
102 | * @param forceRefresh the flag value to set |
103 | */ |
104 | public void setForceRefresh(boolean forceRefresh) { |
105 | this.forceRefresh = forceRefresh; |
106 | } |
107 | |
108 | public Object doWithRetry(RetryContext context) throws Throwable { |
109 | return callback.doWithRetry(context); |
110 | // N.B. code used to check here for isExhaustedOnly and throw exception. |
111 | // This is unnecessary because the callback could just throw the |
112 | // exception itself if it wants to go to the recovery path. |
113 | } |
114 | |
115 | public Object getItem() { |
116 | return item; |
117 | } |
118 | |
119 | public boolean isForceRefresh() { |
120 | return forceRefresh; |
121 | } |
122 | |
123 | /** |
124 | * Accessor for the {@link RecoveryCallback}. |
125 | * |
126 | * @return the {@link RecoveryCallback}. |
127 | */ |
128 | public RecoveryCallback getRecoveryCallback() { |
129 | return recoverer; |
130 | } |
131 | |
132 | } |