Resolves checkstyle errors for callback, chain, circuit-breaker (#1060)

* Reduces checkstyle errors in callback

* Reduces checkstyle errors in chain

* Reduces checkstyle errors in circuit-breaker
This commit is contained in:
Anurag Agarwal 2019-11-10 00:57:14 +05:30 committed by Ilkka Seppälä
parent efc17fcc70
commit 31f27a720b
18 changed files with 114 additions and 125 deletions

View File

@ -23,16 +23,14 @@
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger; import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
/** /**
* * Callback pattern is more native for functional languages where functions are treated as
* Callback pattern is more native for functional languages where functions are * first-class citizens. Prior to Java 8 callbacks can be simulated using simple (alike command)
* treated as first-class citizens. Prior to Java 8 callbacks can be simulated * interfaces.
* using simple (alike command) interfaces.
*
*/ */
public final class App { public final class App {
@ -42,7 +40,7 @@ public final class App {
} }
/** /**
* Program entry point * Program entry point.
*/ */
public static void main(final String[] args) { public static void main(final String[] args) {
Task task = new SimpleTask(); Task task = new SimpleTask();

View File

@ -24,9 +24,7 @@
package com.iluwatar.callback; package com.iluwatar.callback;
/** /**
* * Callback interface.
* Callback interface
*
*/ */
public interface Callback { public interface Callback {

View File

@ -23,24 +23,23 @@
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger; import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
/** /**
* * This example generates the exact same output as {@link App} however the callback has been defined
* This example generates the exact same output as {@link App} however the * as a Lambdas expression.
* callback has been defined as a Lambdas expression.
*
*/ */
public final class LambdasApp { public final class LambdasApp {
private static final Logger LOGGER = getLogger(LambdasApp.class); private static final Logger LOGGER = getLogger(LambdasApp.class);
private LambdasApp() { } private LambdasApp() {
}
/** /**
* Program entry point * Program entry point.
*/ */
public static void main(final String[] args) { public static void main(final String[] args) {
Task task = new SimpleTask(); Task task = new SimpleTask();

View File

@ -23,14 +23,12 @@
package com.iluwatar.callback; package com.iluwatar.callback;
import org.slf4j.Logger;
import static org.slf4j.LoggerFactory.getLogger; import static org.slf4j.LoggerFactory.getLogger;
import org.slf4j.Logger;
/** /**
* * Implementation of task that need to be executed.
* Implementation of task that need to be executed
*
*/ */
public final class SimpleTask extends Task { public final class SimpleTask extends Task {
@ -39,6 +37,6 @@ public final class SimpleTask extends Task {
@Override @Override
public void execute() { public void execute() {
LOGGER.info("Perform some important activity and after call the" LOGGER.info("Perform some important activity and after call the"
+ " callback method."); + " callback method.");
} }
} }

View File

@ -24,14 +24,12 @@
package com.iluwatar.callback; package com.iluwatar.callback;
/** /**
* * Template-method class for callback hook execution.
* Template-method class for callback hook execution
*
*/ */
public abstract class Task { public abstract class Task {
/** /**
* Execute with callback * Execute with callback.
*/ */
final void executeWith(final Callback callback) { final void executeWith(final Callback callback) {
execute(); execute();

View File

@ -24,23 +24,21 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
*
* The Chain of Responsibility pattern is a design pattern consisting of command objects and a * The Chain of Responsibility pattern is a design pattern consisting of command objects and a
* series of processing objects. Each processing object contains logic that defines the types of * series of processing objects. Each processing object contains logic that defines the types of
* command objects that it can handle; the rest are passed to the next processing object in the * command objects that it can handle; the rest are passed to the next processing object in the
* chain. A mechanism also exists for adding new processing objects to the end of this chain. * chain. A mechanism also exists for adding new processing objects to the end of this chain.
* <p> *
* In this example we organize the request handlers ({@link RequestHandler}) into a chain where each * <p>In this example we organize the request handlers ({@link RequestHandler}) into a chain where
* handler has a chance to act on the request on its turn. Here the king ({@link OrcKing}) makes * each handler has a chance to act on the request on its turn. Here the king ({@link OrcKing})
* requests and the military orcs ({@link OrcCommander}, {@link OrcOfficer}, {@link OrcSoldier}) * makes requests and the military orcs ({@link OrcCommander}, {@link OrcOfficer}, {@link
* form the handler chain. * OrcSoldier}) form the handler chain.
*
*/ */
public class App { public class App {
/** /**
* Program entry point * Program entry point.
* *
* @param args command line args * @param args command line args
*/ */
public static void main(String[] args) { public static void main(String[] args) {

View File

@ -24,9 +24,7 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
* * OrcCommander.
* OrcCommander
*
*/ */
public class OrcCommander extends RequestHandler { public class OrcCommander extends RequestHandler {

View File

@ -24,9 +24,7 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
*
* OrcKing makes requests that are handled by the chain. * OrcKing makes requests that are handled by the chain.
*
*/ */
public class OrcKing { public class OrcKing {

View File

@ -24,9 +24,7 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
* * OrcOfficer.
* OrcOfficer
*
*/ */
public class OrcOfficer extends RequestHandler { public class OrcOfficer extends RequestHandler {

View File

@ -24,9 +24,7 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
* * OrcSoldier.
* OrcSoldier
*
*/ */
public class OrcSoldier extends RequestHandler { public class OrcSoldier extends RequestHandler {

View File

@ -26,24 +26,24 @@ package com.iluwatar.chain;
import java.util.Objects; import java.util.Objects;
/** /**
* Request * Request.
*/ */
public class Request { public class Request {
/** /**
* The type of this request, used by each item in the chain to see if they should or can handle * The type of this request, used by each item in the chain to see if they should or can handle
* this particular request * this particular request.
*/ */
private final RequestType requestType; private final RequestType requestType;
/** /**
* A description of the request * A description of the request.
*/ */
private final String requestDescription; private final String requestDescription;
/** /**
* Indicates if the request is handled or not. A request can only switch state from unhandled to * Indicates if the request is handled or not. A request can only switch state from unhandled to
* handled, there's no way to 'unhandle' a request * handled, there's no way to 'unhandle' a request.
*/ */
private boolean handled; private boolean handled;
@ -59,7 +59,7 @@ public class Request {
} }
/** /**
* Get a description of the request * Get a description of the request.
* *
* @return A human readable description of the request * @return A human readable description of the request
*/ */
@ -69,7 +69,7 @@ public class Request {
/** /**
* Get the type of this request, used by each person in the chain of command to see if they should * Get the type of this request, used by each person in the chain of command to see if they should
* or can handle this particular request * or can handle this particular request.
* *
* @return The request type * @return The request type
*/ */
@ -78,14 +78,14 @@ public class Request {
} }
/** /**
* Mark the request as handled * Mark the request as handled.
*/ */
public void markHandled() { public void markHandled() {
this.handled = true; this.handled = true;
} }
/** /**
* Indicates if this request is handled or not * Indicates if this request is handled or not.
* *
* @return <tt>true</tt> when the request is handled, <tt>false</tt> if not * @return <tt>true</tt> when the request is handled, <tt>false</tt> if not
*/ */

View File

@ -27,9 +27,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
/** /**
* * RequestHandler.
* RequestHandler
*
*/ */
public abstract class RequestHandler { public abstract class RequestHandler {
@ -42,7 +40,7 @@ public abstract class RequestHandler {
} }
/** /**
* Request handler * Request handler.
*/ */
public void handleRequest(Request req) { public void handleRequest(Request req) {
if (next != null) { if (next != null) {

View File

@ -24,9 +24,7 @@
package com.iluwatar.chain; package com.iluwatar.chain;
/** /**
* * RequestType enumeration.
* RequestType enumeration
*
*/ */
public enum RequestType { public enum RequestType {

View File

@ -28,42 +28,39 @@ import org.slf4j.LoggerFactory;
/** /**
* <p> * <p>
* The intention of the Circuit Builder pattern is to handle remote failures * The intention of the Circuit Builder pattern is to handle remote failures robustly, which is to
* robustly, which is to mean that if a service is dependant on n number of * mean that if a service is dependant on n number of other services, and m of them fail, we should
* other services, and m of them fail, we should be able to recover from that * be able to recover from that failure by ensuring that the user can still use the services that
* failure by ensuring that the user can still use the services that are actually * are actually functional, and resources are not tied up by uselessly by the services which are not
* functional, and resources are not tied up by uselessly by the services which * working. However, we should also be able to detect when any of the m failing services become
* are not working. However, we should also be able to detect when any of the m * operational again, so that we can use it
* failing services become operational again, so that we can use it
* </p> * </p>
* <p> * <p>
* In this example, the circuit breaker pattern is demonstrated by using two services: * In this example, the circuit breaker pattern is demonstrated by using two services: {@link
* {@link MonitoringService} and {@link DelayedService}. The monitoring service * MonitoringService} and {@link DelayedService}. The monitoring service is responsible for calling
* is responsible for calling two services: a local service and a remote service {@link DelayedService} * two services: a local service and a remote service {@link DelayedService} , and by using the
* , and by using the circuit breaker construction we ensure that if the call to * circuit breaker construction we ensure that if the call to remote service is going to fail, we
* remote service is going to fail, we are going to save our resources and not make the * are going to save our resources and not make the function call at all, by wrapping our call to
* function call at all, by wrapping our call to the remote service in the circuit * the remote service in the circuit breaker object.
* breaker object.
* </p> * </p>
* <p> * <p>
* This works as follows: The {@link CircuitBreaker} object can be in one of three * This works as follows: The {@link CircuitBreaker} object can be in one of three states:
* states: <b>Open</b>, <b>Closed</b> and <b>Half-Open</b>, which represents the real * <b>Open</b>, <b>Closed</b> and <b>Half-Open</b>, which represents the real world circuits. If the
* world circuits. If the state is closed (initial), we assume everything is alright * state is closed (initial), we assume everything is alright and perform the function call.
* and perform the function call. However, every time the call fails, we note it * However, every time the call fails, we note it and once it crosses a threshold, we set the state
* and once it crosses a threshold, we set the state to Open, preventing any further * to Open, preventing any further calls to the remote server. Then, after a certain retry period
* calls to the remote server. Then, after a certain retry period (during which we * (during which we expect thee service to recover), we make another call to the remote server and
* expect thee service to recover), we make another call to the remote server and * this state is called the Half-Open state, where it stays till the service is down, and once it
* this state is called the Half-Open state, where it stays till the service is down, * recovers, it goes back to the closed state and the cycle continues.
* and once it recovers, it goes back to the closed state and the cycle continues.
* </p> * </p>
*/ */
public class App { public class App {
private static final Logger LOGGER = LoggerFactory.getLogger(App.class); private static final Logger LOGGER = LoggerFactory.getLogger(App.class);
/** /**
* Program entry point * Program entry point.
* *
* @param args command line args * @param args command line args
*/ */
@SuppressWarnings("squid:S2189") @SuppressWarnings("squid:S2189")
@ -71,14 +68,14 @@ public class App {
//Create an object of monitoring service which makes both local and remote calls //Create an object of monitoring service which makes both local and remote calls
var obj = new MonitoringService(); var obj = new MonitoringService();
//Set the circuit Breaker parameters //Set the circuit Breaker parameters
var circuitBreaker = new CircuitBreaker(3000, 1, 2000 * 1000 * 1000); var circuitBreaker = new CircuitBreaker(3000, 1, 2000 * 1000 * 1000);
var serverStartTime = System.nanoTime(); var serverStartTime = System.nanoTime();
while (true) { while (true) {
LOGGER.info(obj.localResourceResponse()); LOGGER.info(obj.localResourceResponse());
LOGGER.info(obj.remoteResourceResponse(circuitBreaker, serverStartTime)); LOGGER.info(obj.remoteResourceResponse(circuitBreaker, serverStartTime));
LOGGER.info(circuitBreaker.getState()); LOGGER.info(circuitBreaker.getState());
try { try {
Thread.sleep(5 * 1000); Thread.sleep(5 * 1000);
} catch (InterruptedException e) { } catch (InterruptedException e) {
LOGGER.error(e.getMessage()); LOGGER.error(e.getMessage());
} }

View File

@ -24,7 +24,7 @@
package com.iluwatar.circuitbreaker; package com.iluwatar.circuitbreaker;
/** /**
* The circuit breaker class with all configurations * The circuit breaker class with all configurations.
*/ */
public class CircuitBreaker { public class CircuitBreaker {
private final long timeout; private final long timeout;
@ -36,27 +36,31 @@ public class CircuitBreaker {
private final long futureTime = 1000 * 1000 * 1000 * 1000; private final long futureTime = 1000 * 1000 * 1000 * 1000;
/** /**
* Constructor to create an instance of Circuit Breaker * Constructor to create an instance of Circuit Breaker.
* @param timeout Timeout for the API request. Not necessary for this simple example *
* @param failureThreshold Number of failures we receive from the depended service before changing state to 'OPEN' * @param timeout Timeout for the API request. Not necessary for this simple example
* @param retryTimePeriod Time period after which a new request is made to remote service for status check. * @param failureThreshold Number of failures we receive from the depended service before changing
* state to 'OPEN'
* @param retryTimePeriod Time period after which a new request is made to remote service for
* status check.
*/ */
CircuitBreaker(long timeout, int failureThreshold, long retryTimePeriod) { CircuitBreaker(long timeout, int failureThreshold, long retryTimePeriod) {
// We start in a closed state hoping that everything is fine // We start in a closed state hoping that everything is fine
this.state = State.CLOSED; this.state = State.CLOSED;
this.failureThreshold = failureThreshold; this.failureThreshold = failureThreshold;
// Timeout for the API request. Used to break the calls made to remote resource if it exceeds the limit // Timeout for the API request.
// Used to break the calls made to remote resource if it exceeds the limit
this.timeout = timeout; this.timeout = timeout;
this.retryTimePeriod = retryTimePeriod; this.retryTimePeriod = retryTimePeriod;
//An absurd amount of time in future which basically indicates the last failure never happened //An absurd amount of time in future which basically indicates the last failure never happened
this.lastFailureTime = System.nanoTime() + futureTime; this.lastFailureTime = System.nanoTime() + futureTime;
this.failureCount = 0; this.failureCount = 0;
} }
//Reset everything to defaults //Reset everything to defaults
private void reset() { private void reset() {
this.failureCount = 0; this.failureCount = 0;
this.lastFailureTime = System.nanoTime() + futureTime; this.lastFailureTime = System.nanoTime() + futureTime;
this.state = State.CLOSED; this.state = State.CLOSED;
} }
@ -64,7 +68,7 @@ public class CircuitBreaker {
failureCount = failureCount + 1; failureCount = failureCount + 1;
this.lastFailureTime = System.nanoTime(); this.lastFailureTime = System.nanoTime();
} }
protected void setState() { protected void setState() {
if (failureCount > failureThreshold) { //Then something is wrong with remote service if (failureCount > failureThreshold) { //Then something is wrong with remote service
if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) { if ((System.nanoTime() - lastFailureTime) > retryTimePeriod) {
@ -79,23 +83,28 @@ public class CircuitBreaker {
state = State.CLOSED; state = State.CLOSED;
} }
} }
public String getState() { public String getState() {
return state.name(); return state.name();
} }
/** /**
* Break the circuit beforehand if it is known service is down * Break the circuit beforehand if it is known service is down Or connect the circuit manually if
* Or connect the circuit manually if service comes online before expected * service comes online before expected.
*
* @param state State at which circuit is in * @param state State at which circuit is in
*/ */
public void setStateForBypass(State state) { public void setStateForBypass(State state) {
this.state = state; this.state = state;
} }
/** /**
* @param serviceToCall The name of the service in String. Can be changed to data URLs in case of web applications * Executes service call.
* @param serverStartTime Time at which actual server was started which makes calls to this service *
* @param serviceToCall The name of the service in String. Can be changed to data URLs in case
* of web applications
* @param serverStartTime Time at which actual server was started which makes calls to this
* service
* @return Value from the remote resource, stale response or a custom exception * @return Value from the remote resource, stale response or a custom exception
*/ */
public String call(String serviceToCall, long serverStartTime) throws Exception { public String call(String serviceToCall, long serverStartTime) throws Exception {
@ -104,7 +113,7 @@ public class CircuitBreaker {
// return cached response if no the circuit is in OPEN state // return cached response if no the circuit is in OPEN state
return "This is stale response from API"; return "This is stale response from API";
} else { } else {
// Make the API request if the circuit is not OPEN // Make the API request if the circuit is not OPEN
if (serviceToCall.equals("delayedService")) { if (serviceToCall.equals("delayedService")) {
var delayedService = new DelayedService(20); var delayedService = new DelayedService(20);
var response = delayedService.response(serverStartTime); var response = delayedService.response(serverStartTime);

View File

@ -24,14 +24,15 @@
package com.iluwatar.circuitbreaker; package com.iluwatar.circuitbreaker;
/** /**
* This simulates the remote service * This simulates the remote service It responds only after a certain timeout period (default set to
* It responds only after a certain timeout period (default set to 20 seconds) * 20 seconds).
*/ */
public class DelayedService { public class DelayedService {
private final int delay; private final int delay;
/** /**
* Constructor to create an instance of DelayedService, which is down for first few seconds * Constructor to create an instance of DelayedService, which is down for first few seconds.
*
* @param delay the delay after which service would behave properly, in seconds * @param delay the delay after which service would behave properly, in seconds
*/ */
public DelayedService(int delay) { public DelayedService(int delay) {
@ -43,7 +44,10 @@ public class DelayedService {
} }
/** /**
* @param serverStartTime Time at which actual server was started which makes calls to this service * Responds based on delay, current time and server start time if the service is down / working.
*
* @param serverStartTime Time at which actual server was started which makes calls to this
* service
* @return The state of the service * @return The state of the service
*/ */
public String response(long serverStartTime) { public String response(long serverStartTime) {

View File

@ -24,8 +24,8 @@
package com.iluwatar.circuitbreaker; package com.iluwatar.circuitbreaker;
/** /**
* The service class which makes local and remote calls * The service class which makes local and remote calls Uses {@link CircuitBreaker} object to ensure
* Uses {@link CircuitBreaker} object to ensure remote calls don't use up resources * remote calls don't use up resources.
*/ */
public class MonitoringService { public class MonitoringService {
@ -35,9 +35,11 @@ public class MonitoringService {
} }
/** /**
* Try to get result from remote server * Try to get result from remote server.
* @param circuitBreaker The circuitBreaker object with all parameters *
* @param serverStartTime Time at which actual server was started which makes calls to this service * @param circuitBreaker The circuitBreaker object with all parameters
* @param serverStartTime Time at which actual server was started which makes calls to this
* service
* @return result from the remote response or exception raised by it. * @return result from the remote response or exception raised by it.
*/ */
public String remoteResourceResponse(CircuitBreaker circuitBreaker, long serverStartTime) { public String remoteResourceResponse(CircuitBreaker circuitBreaker, long serverStartTime) {

View File

@ -24,10 +24,10 @@
package com.iluwatar.circuitbreaker; package com.iluwatar.circuitbreaker;
/** /**
* Enumeration for states the circuit breaker could be in * Enumeration for states the circuit breaker could be in.
*/ */
public enum State { public enum State {
CLOSED, CLOSED,
OPEN, OPEN,
HALF_OPEN HALF_OPEN
} }