Skip to content

Commit

Permalink
addressed all javadoc warnings (#11)
Browse files Browse the repository at this point in the history
* Also added a NOOP implementation of FailureFlags

Signed-off-by: Jeff Nickoloff <[email protected]>
  • Loading branch information
allingeek authored Sep 25, 2023
1 parent dc680ab commit 0d49e5b
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 13 deletions.
14 changes: 14 additions & 0 deletions src/main/java/com/gremlin/failureflags/Behavior.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
package com.gremlin.failureflags;

/**
* Behaviors implement specific effects or symptoms of failures that an application will experience in calls to
* FailureFlags.invoke(...). When processing multiple experiments, delays should be applied before other failure types
* and those failure types that can be processed without changing flow should be applied first. If multiple experiments
* result in changing control flow (like exceptions, shutdowns, panics, etc.) then the behavior chain may not realize
* some effects.
*
* This is a functional interface. An adopter might use Lambdas to provide behavior inline.
* */
@FunctionalInterface
public interface Behavior {
/**
* applyBehavior applies any behavior described by the effect statements in each experiment in the provided array.
*
* @param experiments an ordered array of active Experiments to apply
* */
void applyBehavior(Experiment[] experiments);
}
42 changes: 35 additions & 7 deletions src/main/java/com/gremlin/failureflags/Experiment.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,70 @@
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.Map;

/**
* Experiment describes an active experiment defined by a Gremlin user.
* */
@JsonIgnoreProperties(ignoreUnknown = true)
public class Experiment {
String name;
String guid;
float rate;
Map<String, Object> effect;

/**
* getName() returns the name of the experiment.
* @return the name of the experiment
* */
public String getName() {
return name;
}

/**
* setName() sets the name of the experiment.
* @param name the name of the experiment
* */
public void setName(String name) {
this.name = name;
}
/**
* getGuid() returns the GUID of the experiment.
* @return the GUID of the experiment
* */
public String getGuid() {
return guid;
}

/**
* setGuid() sets the GUID of the experiment.
* @param guid the guid of the experiment
* */
public void setGuid(String guid) {
this.guid = guid;
}

/**
* getRate() returns the rate of the experiment.
* @return the rate of the experiment
* */
public float getRate() {
return rate;
}

/**
* setRate() sets the rate of the experiment.
* @param rate the rate of the experiment
* */
public void setRate(float rate) {
this.rate = rate;
}

/**
* getEffect() returns the effect of the experiment.
* @return the effect of the experiment
* */
public Map<String, Object> getEffect() {
return effect;
}

/**
* setEffect() sets the effect of the experiment.
* @param effect the effect of the experiment
* */
public void setEffect(Map<String, Object> effect) {
this.effect = effect;
}

}
34 changes: 32 additions & 2 deletions src/main/java/com/gremlin/failureflags/FailureFlag.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,60 @@ public class FailureFlag {
@JsonIgnore
boolean debug;

/**
* Construct a new FailureFlag and set all options.
*
* @param name the name of the FailureFlag
* @param labels the labels of the FailureFlag
* @param debug the debug state of the FailureFlag
* */
public FailureFlag(String name, Map<String, String> labels, boolean debug) {
this.name = name;
this.labels = labels;
this.debug = debug;
}

/**
* getName() returns the name of the FailureFlag.
* @return the name of the FailureFlag
* */
public String getName() {
return name;
}

/**
* setName() sets the name of the FailureFlag.
* @param name the name of the FailureFlag
* */
public void setName(String name) {
this.name = name;
}

/**
* getLabels() returns the labels of the FailureFlag.
* @return the labels of the FailureFlag
* */
public Map<String, String> getLabels() {
return labels;
}

/**
* setLabels() sets the labels of the FailureFlag.
* @param labels the labels of the FailureFlag
* */
public void setLabels(Map<String, String> labels) {
this.labels = labels;
}

/**
* getDebug() returns true if the FailureFlag is configured for debugging.
* @return the debug state of the FailureFlag
* */
public boolean getDebug() { return debug; }
public void setDebug(boolean debug) { this.debug = debug; }


/**
* setDebug() sets the debug state of the FailureFlag.
* @param debug the debug state of the FailureFlag
* */
public void setDebug(boolean debug) { this.debug = debug; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@

import java.util.Map;

/**
* FailureFlagException is an unchecked exception thrown by the Exception behavior while processing an Experiment with
* an <code>exception</code> property on its effect statement.
* */
public class FailureFlagException extends RuntimeException {
/**
* Construct a new FailureFlagException.
* @param message the message to attach to this exception.
* */
public FailureFlagException(final String message) {
super(message);
}

}
13 changes: 11 additions & 2 deletions src/main/java/com/gremlin/failureflags/FailureFlags.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,27 @@
package com.gremlin.failureflags;

/**
* FailureFlags is an interface exposing the core functionality of the FailureFlags system. Code to this interface to
* improve testability of your code. GremlinFailureFlags is the default implementation.
* */
public interface FailureFlags {
/**
* invoke will fetch and apply the provided behaviors for any experiments targeting the provided Failure Flag.
* @param flag the FailureFlag to invoke
* @param behavior the specific or inline behavior to use for any active experiments
* @return an array of active Experiments. null if there are no active experiments targeting the provided Failure Flag.
* */
Experiment[] invoke(FailureFlag flag, Behavior behavior);
/**
* invoke will fetch and apply default behaviors for any experiments targeting the provided Failure Flag.
* @param flag the FailureFlag to invoke
* @return an array of active Experiments. null if there are no active experiments targeting the provided Failure Flag.
* */
Experiment[] invoke(FailureFlag flag);
/**
* fetchExperiment retrieves the list of active experiments targeting the provided Failure Flag.
*
* @return null if there are no active experiments targeting the provided Failure Flag.
* @param flag the FailureFlag to invoke
* @return an array of active Experiments. null if there are no active experiments targeting the provided Failure Flag.
* */
Experiment[] fetch(FailureFlag flag);
}
18 changes: 18 additions & 0 deletions src/main/java/com/gremlin/failureflags/GremlinFailureFlags.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,25 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* GremlinFailureFlags is a full implementation of FailureFlags that integrates with the Gremlin sidecars and API.
* */
public class GremlinFailureFlags implements FailureFlags {

private static final String VERSION = FailureFlags.class.getPackage().getImplementationVersion();
private static final Logger LOGGER = LoggerFactory.getLogger(FailureFlags.class);
private static final String IOEXCEPTION_MESSAGE = "IOException during HTTP call to Gremlin co-process";
private static final ObjectMapper MAPPER = new ObjectMapper();

/**
* FAILURE_FLAGS_ENABLED contains the name of the environment variable to use to control the enabled status of this SDK.
* */
public static final String FAILURE_FLAGS_ENABLED = "FAILURE_FLAGS_ENABLED";

private final Behavior defaultBehavior;
/**
* enabled overrides any environment configuration to enable or disable this SDK. Setting to true will enable this SDK.
* */
protected boolean enabled; // for testing purposes

/**
Expand All @@ -41,6 +50,8 @@ public GremlinFailureFlags() {

/**
* Construct a new FailureFlags instance with a different default behavior chain.
* @param defaultBehavior the default behavior to use in all calls to <code>invoke</code> unless overridden by
* parameter on that specific invocation.
* */
public GremlinFailureFlags(Behavior defaultBehavior) {
if (defaultBehavior == null) {
Expand All @@ -49,20 +60,26 @@ public GremlinFailureFlags(Behavior defaultBehavior) {
this.defaultBehavior = defaultBehavior;
}

/**
* getDefaultBehavior returns the current Behavior to be used in default invocations.
* @return the default behavior
* */
public Behavior getDefaultBehavior() {
return this.defaultBehavior;
}

/**
* {@inheritDoc}
* */
@Override
public Experiment[] invoke(FailureFlag flag) {
return invoke(flag, null);
}

/**
* {@inheritDoc}
* */
@Override
public Experiment[] invoke(FailureFlag flag, Behavior behavior) {
if (!System.getenv().containsKey(FAILURE_FLAGS_ENABLED) && !this.enabled) {
return null;
Expand Down Expand Up @@ -119,6 +136,7 @@ public Experiment[] invoke(FailureFlag flag, Behavior behavior) {
/**
* {@inheritDoc}
* */
@Override
public Experiment[] fetch(FailureFlag flag) {
if (flag == null) {
return null;
Expand Down
21 changes: 21 additions & 0 deletions src/main/java/com/gremlin/failureflags/NoopFailureFlags.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.gremlin.failureflags;

/**
* NoopFailureFlags is a stub implementation of FailureFlags. It does nothing and its methods always return null.
* */
public class NoopFailureFlags implements FailureFlags {
@Override
public Experiment[] invoke(FailureFlag flag, Behavior behavior) {
return null;
}

@Override
public Experiment[] invoke(FailureFlag flag) {
return null;
}

@Override
public Experiment[] fetch(FailureFlag flag) {
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,16 @@
import com.gremlin.failureflags.Behavior;
import com.gremlin.failureflags.Experiment;

/**
* DelayedException processes <code>latency</code> and <code>exception</code> properties in experiment effects. All
* latency effects will be applied before any exceptions are thrown.
*
* Behaviors implement specific effects or symptoms of failures that an application will experience in calls to
* FailureFlags.invoke(...). When processing multiple experiments, delays should be applied before other failure types
* and those failure types that can be processed without changing flow should be applied first. If multiple experiments
* result in changing control flow (like exceptions, shutdowns, panics, etc.) then the behavior chain may not realize
* some effects.
* */
public class DelayedException implements Behavior {
public void applyBehavior(Experiment[] experiments) {
new Latency().applyBehavior(experiments);
Expand Down
11 changes: 10 additions & 1 deletion src/main/java/com/gremlin/failureflags/behaviors/Exception.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,17 @@
import com.gremlin.failureflags.Behavior;
import com.gremlin.failureflags.FailureFlagException;
import com.gremlin.failureflags.Experiment;

/**
* Exception processes <code>exception</code> properties in experiment effects.
*
* Behaviors implement specific effects or symptoms of failures that an application will experience in calls to
* FailureFlags.invoke(...). When processing multiple experiments, delays should be applied before other failure types
* and those failure types that can be processed without changing flow should be applied first. If multiple experiments
* result in changing control flow (like exceptions, shutdowns, panics, etc.) then the behavior chain may not realize
* some effects.
* */
public class Exception implements Behavior {
/**{@inheritDoc}*/
public void applyBehavior(Experiment[] experiments) {
for (Experiment e: experiments) {
if (!e.getEffect().containsKey("exception")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
* */
public class Latency implements Behavior {

/**{@inheritDoc}*/
public void applyBehavior(Experiment[] experiments) {
for (Experiment e: experiments) {
if (!e.getEffect().containsKey("latency")) { continue; }
Expand Down

0 comments on commit 0d49e5b

Please sign in to comment.