Skip to content

Commit 8c35bc8

Browse files
Merge pull request #22 from BorderTech/refactor-submodules
ServiceHelper API new checked exceptions.
2 parents 582c6c4 + 63c0dd0 commit 8c35bc8

File tree

9 files changed

+433
-261
lines changed

9 files changed

+433
-261
lines changed

taskmaster-service-helper/src/main/java/com/github/bordertech/taskmaster/service/ServiceHelper.java

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.github.bordertech.taskmaster.service;
22

3-
import com.github.bordertech.taskmaster.RejectedTaskException;
3+
import com.github.bordertech.taskmaster.service.exception.AsyncServiceException;
4+
import com.github.bordertech.taskmaster.service.exception.RejectedServiceException;
45
import java.io.Serializable;
56
import javax.cache.Cache;
67
import javax.cache.expiry.Duration;
@@ -12,20 +13,6 @@
1213
*/
1314
public interface ServiceHelper {
1415

15-
/**
16-
* This is the method checks if the processing task has completed.
17-
* <p>
18-
* If the future is done, then it will transition the result from the processing cache into the result holder cache.
19-
* </p>
20-
*
21-
* @param cache the result holder cache
22-
* @param cacheKey the key for the result holder
23-
* @param <S> the criteria type
24-
* @param <T> the service response
25-
* @return the result or null if still processing
26-
*/
27-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> checkASyncResult(final Cache<String, ResultHolder> cache, final String cacheKey);
28-
2916
/**
3017
* Provide a default result holder cache with the default duration.
3118
*
@@ -60,10 +47,10 @@ public interface ServiceHelper {
6047
* @param <S> the criteria type
6148
* @param <T> the service response
6249
* @return the result or null if still processing
63-
* @throws RejectedTaskException if the task cannot be scheduled for execution
50+
* @throws RejectedServiceException if the task cannot be scheduled for execution
6451
*/
65-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache, final String cacheKey,
66-
final S criteria, final ServiceAction<S, T> action) throws RejectedTaskException;
52+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache,
53+
final String cacheKey, final S criteria, final ServiceAction<S, T> action) throws RejectedServiceException;
6754

6855
/**
6956
* Handle an async service call with a designated thread pool.
@@ -76,10 +63,10 @@ <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncS
7663
* @param <S> the criteria type
7764
* @param <T> the service response
7865
* @return the result or null if still processing
79-
* @throws RejectedTaskException if the task cannot be scheduled for execution
66+
* @throws RejectedServiceException if the task cannot be scheduled for execution
8067
*/
81-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache, final String cacheKey,
82-
final S criteria, final ServiceAction<S, T> action, final String pool) throws RejectedTaskException;
68+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache,
69+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final String pool) throws RejectedServiceException;
8370

8471
/**
8572
*
@@ -93,8 +80,8 @@ <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncS
9380
* @param <T> the service response
9481
* @return the result
9582
*/
96-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleCachedServiceCall(final Cache<String, ResultHolder> cache, final String cacheKey,
97-
final S criteria, final ServiceAction<S, T> action);
83+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleCachedServiceCall(final Cache<String, ResultHolder> cache,
84+
final String cacheKey, final S criteria, final ServiceAction<S, T> action);
9885

9986
/**
10087
* Handle a service call.
@@ -119,10 +106,10 @@ <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleCached
119106
* @param <S> the criteria type
120107
* @param <T> the service response
121108
* @return the result or null if still processing an async call
122-
* @throws RejectedTaskException if the task cannot be scheduled for execution
109+
* @throws RejectedServiceException if the task cannot be scheduled for execution
123110
*/
124-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache, final String cacheKey,
125-
final S criteria, final ServiceAction<S, T> action, final CallType callType) throws RejectedTaskException;
111+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache,
112+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final CallType callType) throws RejectedServiceException;
126113

127114
/**
128115
*
@@ -137,9 +124,25 @@ <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServic
137124
* @param <S> the criteria type
138125
* @param <T> the service response
139126
* @return the result or null if still processing an async call
140-
* @throws RejectedTaskException if the task cannot be scheduled for execution
127+
* @throws RejectedServiceException if the task cannot be scheduled for execution
128+
*/
129+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache,
130+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final CallType callType, final String pool) throws RejectedServiceException;
131+
132+
/**
133+
* This is the method that checks if the processing task has completed.
134+
* <p>
135+
* It the task is complete it will return the result and put the result in the result cache.
136+
* </p>
137+
*
138+
* @param cache the result holder cache
139+
* @param cacheKey the key for the result holder
140+
* @param <S> the criteria type
141+
* @param <T> the service response
142+
* @return the result or null if still processing
143+
* @throws AsyncServiceException an exception while processing an Async task
141144
*/
142-
<S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache, final String cacheKey,
143-
final S criteria, final ServiceAction<S, T> action, final CallType callType, final String pool) throws RejectedTaskException;
145+
<S extends Serializable, T extends Serializable> ResultHolder<S, T> checkASyncResult(final Cache<String, ResultHolder> cache,
146+
final String cacheKey) throws AsyncServiceException;
144147

145148
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.github.bordertech.taskmaster.service.exception;
2+
3+
/**
4+
* Service Helper had an exception processing the Async task.
5+
*
6+
* @author Jonathan Austin
7+
* @since 1.0.0
8+
*/
9+
public class AsyncServiceException extends Exception {
10+
11+
/**
12+
* Creates a AsyncServiceException with the specified message.
13+
*
14+
* @param msg the message.
15+
*/
16+
public AsyncServiceException(final String msg) {
17+
super(msg);
18+
}
19+
20+
/**
21+
* Creates a AsyncServiceException with the specified message and cause.
22+
*
23+
* @param msg the message.
24+
* @param throwable the cause of the exception.
25+
*/
26+
public AsyncServiceException(final String msg, final Throwable throwable) {
27+
super(msg, throwable);
28+
}
29+
30+
/**
31+
* Creates a RejectedExcepAsyncServiceExceptionion with the specified cause.
32+
*
33+
* @param throwable the cause of the exception.
34+
*/
35+
public AsyncServiceException(final Throwable throwable) {
36+
super(throwable);
37+
}
38+
}

taskmaster-service-helper/src/main/java/com/github/bordertech/taskmaster/service/ExceptionUtil.java renamed to taskmaster-service-helper/src/main/java/com/github/bordertech/taskmaster/service/exception/ExceptionUtil.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.bordertech.taskmaster.service;
1+
package com.github.bordertech.taskmaster.service.exception;
22

33
import java.io.ByteArrayOutputStream;
44
import java.io.ObjectOutputStream;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.github.bordertech.taskmaster.service.exception;
2+
3+
/**
4+
* Service Helper could not execute this task.
5+
*
6+
* @author Jonathan Austin
7+
* @since 1.0.0
8+
*/
9+
public class RejectedServiceException extends Exception {
10+
11+
/**
12+
* Creates a RejectedException with the specified message.
13+
*
14+
* @param msg the message.
15+
*/
16+
public RejectedServiceException(final String msg) {
17+
super(msg);
18+
}
19+
20+
/**
21+
* Creates a RejectedException with the specified message and cause.
22+
*
23+
* @param msg the message.
24+
* @param throwable the cause of the exception.
25+
*/
26+
public RejectedServiceException(final String msg, final Throwable throwable) {
27+
super(msg, throwable);
28+
}
29+
30+
/**
31+
* Creates a RejectedException with the specified cause.
32+
*
33+
* @param throwable the cause of the exception.
34+
*/
35+
public RejectedServiceException(final Throwable throwable) {
36+
super(throwable);
37+
}
38+
}

taskmaster-service-helper/src/main/java/com/github/bordertech/taskmaster/service/ServiceException.java renamed to taskmaster-service-helper/src/main/java/com/github/bordertech/taskmaster/service/exception/ServiceException.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package com.github.bordertech.taskmaster.service;
1+
package com.github.bordertech.taskmaster.service.exception;
22

33
/**
44
* Service exception that can be thrown while processing a service request.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/**
2+
* Service Helper Exceptions.
3+
*/
4+
package com.github.bordertech.taskmaster.service.exception;
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
package com.github.bordertech.taskmaster.service.impl;
2+
3+
import com.github.bordertech.taskmaster.service.CallType;
4+
import com.github.bordertech.taskmaster.service.ResultHolder;
5+
import com.github.bordertech.taskmaster.service.ServiceAction;
6+
import com.github.bordertech.taskmaster.service.ServiceHelper;
7+
import com.github.bordertech.taskmaster.service.exception.AsyncServiceException;
8+
import com.github.bordertech.taskmaster.service.exception.ExceptionUtil;
9+
import com.github.bordertech.taskmaster.service.exception.RejectedServiceException;
10+
import java.io.Serializable;
11+
import javax.cache.Cache;
12+
import org.apache.commons.logging.Log;
13+
import org.apache.commons.logging.LogFactory;
14+
15+
/**
16+
* Provide a starter implementation of ServiceHelper.
17+
*/
18+
public abstract class AbstractServiceHelper implements ServiceHelper {
19+
20+
private static final Log LOGGER = LogFactory.getLog(AbstractServiceHelper.class);
21+
22+
@Override
23+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCall(final S criteria, final ServiceAction<S, T> action) {
24+
// Check action provided
25+
if (action == null) {
26+
throw new IllegalArgumentException("No service action has been provided. ");
27+
}
28+
29+
// Do service call
30+
try {
31+
T resp = action.service(criteria);
32+
return new ResultHolder(criteria, resp);
33+
} catch (Exception e) {
34+
return new ResultHolder(criteria, ExceptionUtil.getSerializableException(e));
35+
}
36+
}
37+
38+
@Override
39+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache,
40+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final CallType callType)
41+
throws RejectedServiceException {
42+
return handleServiceCallType(cache, cacheKey, criteria, action, callType, null);
43+
}
44+
45+
@Override
46+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleServiceCallType(final Cache<String, ResultHolder> cache,
47+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final CallType callType, final String pool)
48+
throws RejectedServiceException {
49+
if (callType == null) {
50+
throw new IllegalArgumentException("Call type must be provided.");
51+
}
52+
// Refresh the Cache
53+
if (callType.isRefresh()) {
54+
cache.remove(cacheKey);
55+
}
56+
if (callType.isAsync()) {
57+
// ASync
58+
return handleAsyncServiceCall(cache, cacheKey, criteria, action, pool);
59+
} else {
60+
// Sync
61+
return handleCachedServiceCall(cache, cacheKey, criteria, action);
62+
}
63+
}
64+
65+
@Override
66+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleCachedServiceCall(final Cache<String, ResultHolder> cache,
67+
final String cacheKey, final S criteria, final ServiceAction<S, T> action) {
68+
69+
// Check cache and cache key provided
70+
if (cache == null) {
71+
throw new IllegalArgumentException("A cache must be provided.");
72+
}
73+
if (cacheKey == null) {
74+
throw new IllegalArgumentException("A cache key must be provided.");
75+
}
76+
77+
// Check cache for result
78+
ResultHolder cached = cache.get(cacheKey);
79+
if (cached != null) {
80+
LOGGER.debug(buildCacheMessagePrefix(cache, cacheKey) + "Cached service call already in cache.");
81+
return cached;
82+
}
83+
// Do service call
84+
ResultHolder<S, T> result = handleServiceCall(criteria, action);
85+
// Save in the cache
86+
cache.put(cacheKey, result);
87+
88+
return result;
89+
}
90+
91+
@Override
92+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache,
93+
final String cacheKey, final S criteria, final ServiceAction<S, T> action) throws RejectedServiceException {
94+
return handleAsyncServiceCall(cache, cacheKey, criteria, action, null);
95+
}
96+
97+
@Override
98+
public <S extends Serializable, T extends Serializable> ResultHolder<S, T> handleAsyncServiceCall(final Cache<String, ResultHolder> cache,
99+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final String pool) throws RejectedServiceException {
100+
101+
// Check cache and cache key provided
102+
if (cache == null) {
103+
throw new IllegalArgumentException("A cache must be provided for async processing.");
104+
}
105+
if (cacheKey == null) {
106+
throw new IllegalArgumentException("A cache key must be provided for async processing. ");
107+
}
108+
// Check action provided
109+
if (action == null) {
110+
throw new IllegalArgumentException("No service action has been provided. ");
111+
}
112+
113+
// Maybe already in the result cache
114+
ResultHolder cached = cache.get(cacheKey);
115+
if (cached != null) {
116+
LOGGER.debug(buildCacheMessagePrefix(cache, cacheKey) + "Async service call already in cache.");
117+
return cached;
118+
}
119+
120+
// Check already processing
121+
if (isAsyncServiceRunning(cache, cacheKey, criteria, action, pool)) {
122+
LOGGER.debug(buildCacheMessagePrefix(cache, cacheKey) + "Async service call is already processing. A new service call will not be submitted.");
123+
try {
124+
return checkASyncResult(cache, cacheKey);
125+
} catch (AsyncServiceException e) {
126+
LOGGER.debug(buildCacheMessagePrefix(cache, cacheKey) + "Error checking Async service call. Will be ignored and submitted again.");
127+
}
128+
}
129+
130+
// Submit the service call
131+
LOGGER.debug(buildCacheMessagePrefix(cache, cacheKey) + "Async service call will be submitted.");
132+
submitAsyncService(cache, cacheKey, criteria, action, pool);
133+
return null;
134+
}
135+
136+
/**
137+
*
138+
* @param cache the cache result holder
139+
* @param cacheKey the cache key being processed
140+
* @return the message suffix
141+
*/
142+
protected String buildCacheMessagePrefix(final Cache<String, ResultHolder> cache, final String cacheKey) {
143+
return "Cache [" + cache.getName() + "] and key [" + cacheKey + "]. ";
144+
}
145+
146+
/**
147+
* Check if the service is already running.
148+
*
149+
* @param cache the result holder cache
150+
* @param cacheKey the key for the result holder
151+
* @param criteria the criteria
152+
* @param action the service action
153+
* @param pool the service thread pool
154+
* @param <S> the criteria type
155+
* @param <T> the service response
156+
* @return true if task is already running
157+
*/
158+
protected abstract <S extends Serializable, T extends Serializable> boolean isAsyncServiceRunning(final Cache<String, ResultHolder> cache,
159+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final String pool);
160+
161+
/**
162+
* Submit the async service call.
163+
*
164+
* @param cache the result holder cache
165+
* @param cacheKey the key for the result holder
166+
* @param criteria the criteria
167+
* @param action the service action
168+
* @param pool the service thread pool
169+
* @param <S> the criteria type
170+
* @param <T> the service response
171+
* @throws RejectedServiceException if the task cannot be scheduled for execution
172+
*/
173+
protected abstract <S extends Serializable, T extends Serializable> void submitAsyncService(final Cache<String, ResultHolder> cache,
174+
final String cacheKey, final S criteria, final ServiceAction<S, T> action, final String pool)
175+
throws RejectedServiceException;
176+
177+
}

0 commit comments

Comments
 (0)