View Javadoc
1   package emissary.core.sentinel.protocols;
2   
3   import emissary.config.Configurator;
4   import emissary.core.Factory;
5   import emissary.core.sentinel.protocols.actions.Action;
6   import emissary.core.sentinel.protocols.actions.Notify;
7   import emissary.core.sentinel.protocols.rules.Rule;
8   
9   import org.apache.commons.collections4.MapUtils;
10  import org.slf4j.Logger;
11  import org.slf4j.LoggerFactory;
12  
13  import java.io.IOException;
14  import java.lang.invoke.MethodHandles;
15  import java.util.Map;
16  import java.util.concurrent.ConcurrentHashMap;
17  
18  /**
19   * Protocols are configured with a list of rules that trigger some action if all conditions are met.
20   */
21  public abstract class Protocol {
22  
23      protected static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
24  
25      protected Configurator config;
26      protected final Map<String, Rule> rules = new ConcurrentHashMap<>();
27      protected Action action;
28      protected boolean enabled = false;
29  
30      protected Protocol() {}
31  
32      public Protocol(Configurator config) {
33          configure(config);
34      }
35  
36      public abstract void run() throws IOException;
37  
38      protected abstract Rule<?> getRule(String ruleId) throws IOException;
39  
40      public boolean isEnabled() {
41          return this.enabled && MapUtils.isNotEmpty(this.rules);
42      }
43  
44      protected void configure(final Configurator config) {
45          this.config = config;
46          init();
47      }
48  
49      /**
50       * Initialize rule set and action
51       */
52      protected void init() {
53          this.enabled = this.config.findBooleanEntry("ENABLED", false);
54          this.action = (Action) Factory.create(this.config.findStringEntry("ACTION", Notify.class.getName()));
55  
56          logger.trace("Loading rules...");
57          for (String ruleId : this.config.findEntries("RULE_ID")) {
58              if (this.rules.containsKey(ruleId)) {
59                  logger.warn("Sentinel rule with ID[{}] already exists, this may result in unexpected behavior", ruleId);
60              }
61              try {
62                  final Rule<?> ruleImpl = getRule(ruleId);
63                  this.rules.put(ruleId, ruleImpl);
64                  logger.debug("Sentinel loaded rule[{}] - {}", ruleId, ruleImpl);
65              } catch (Exception e) {
66                  logger.warn("Sentinel rule[{}] is invalid: {}", ruleId, e.getMessage());
67              }
68          }
69  
70          if (this.rules.isEmpty()) {
71              this.enabled = false;
72          }
73      }
74  
75  }