You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by ma...@apache.org on 2017/09/09 03:50:40 UTC

[1/6] metron git commit: METRON-1162 Apply Live Messages to the Profile Debugger (nickwallen) closes apache/metron#736

Repository: metron
Updated Branches:
  refs/heads/Metron_0.4.1 f0ae85fb7 -> 269d42e92


METRON-1162 Apply Live Messages to the Profile Debugger (nickwallen) closes apache/metron#736


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/6ff39ae3
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/6ff39ae3
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/6ff39ae3

Branch: refs/heads/Metron_0.4.1
Commit: 6ff39ae380d82fb5805f4092806b846332c3c8b8
Parents: f0ae85f
Author: nickwallen <ni...@nickallen.org>
Authored: Fri Sep 8 17:15:22 2017 -0400
Committer: nickallen <ni...@apache.org>
Committed: Fri Sep 8 17:15:22 2017 -0400

----------------------------------------------------------------------
 .../client/stellar/ProfilerFunctions.java       | 113 ++++++++++++++-----
 .../client/stellar/ProfilerFunctionsTest.java   |  53 ++++++++-
 2 files changed, 129 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/6ff39ae3/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/stellar/ProfilerFunctions.java
----------------------------------------------------------------------
diff --git a/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/stellar/ProfilerFunctions.java b/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/stellar/ProfilerFunctions.java
index 8df5ca8..d6f2c6a 100644
--- a/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/stellar/ProfilerFunctions.java
+++ b/metron-analytics/metron-profiler-client/src/main/java/org/apache/metron/profiler/client/stellar/ProfilerFunctions.java
@@ -20,6 +20,7 @@
 
 package org.apache.metron.profiler.client.stellar;
 
+import org.apache.commons.collections4.ListUtils;
 import org.apache.metron.common.configuration.profiler.ProfilerConfig;
 import org.apache.metron.common.utils.JSONUtils;
 import org.apache.metron.profiler.ProfileMeasurement;
@@ -41,6 +42,7 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -109,7 +111,7 @@ public class ProfilerFunctions {
           name="APPLY",
           description="Apply a message to a local profile runner.",
           params={
-                  "message(s)", "The message to apply.  A JSON list can be used to apply multiple messages.",
+                  "message(s)", "The message to apply; a JSON string or list of JSON strings.",
                   "profiler", "A local profile runner returned by PROFILER_INIT."
           },
           returns="The local profile runner."
@@ -131,50 +133,99 @@ public class ProfilerFunctions {
     @Override
     public Object apply(List<Object> args, Context context) throws ParseException {
 
-      // user must provide the message as a string
-      String arg0 = Util.getArg(0, String.class, args);
-      if(arg0 == null) {
-        throw new IllegalArgumentException(format("expected string, found null"));
+      // the use can pass in one or more messages in a few different forms
+      Object arg0 = Util.getArg(0, Object.class, args);
+      List<JSONObject> messages = getMessages(arg0);
+
+      // user must provide the stand alone profiler
+      StandAloneProfiler profiler = Util.getArg(1, StandAloneProfiler.class, args);
+      try {
+        for (JSONObject message : messages) {
+          profiler.apply(message);
+        }
+
+      } catch (ExecutionException e) {
+        throw new IllegalArgumentException(format("Failed to apply message; error=%s", e.getMessage()), e);
+      }
+
+      return profiler;
+    }
+
+    /**
+     * Gets a message or messages from the function arguments.
+     *
+     * @param arg The function argument containing the message(s).
+     * @return A list of messages
+     */
+    private List<JSONObject> getMessages(Object arg) {
+      List<JSONObject> messages;
+
+      if (arg instanceof String) {
+        messages = getMessagesFromString((String) arg);
+
+      } else if (arg instanceof Iterable) {
+        messages = getMessagesFromIterable((Iterable<String>) arg);
+
+      } else if (arg instanceof JSONObject) {
+        messages = Collections.singletonList((JSONObject) arg);
+
+      } else {
+        throw new IllegalArgumentException(format("invalid message: found '%s', expected String, List, or JSONObject",
+                ClassUtils.getShortClassName(arg, "null")));
       }
 
-      // there could be one or more messages
+      return messages;
+    }
+
+    /**
+     * Gets a message or messages from a List
+     *
+     * @param strings The function argument that is a bunch of strings.
+     * @return A list of messages.
+     */
+    private List<JSONObject> getMessagesFromIterable(Iterable<String> strings) {
       List<JSONObject> messages = new ArrayList<>();
+
+      // the user pass in a list of strings
+      for (String str : strings) {
+        messages.addAll(getMessagesFromString(str));
+      }
+
+      return messages;
+    }
+
+    /**
+     * Gets a message or messages from a String argument.
+     *
+     * @param arg0 The function argument is just a List.
+     * @return A list of messages.
+     */
+    private List<JSONObject> getMessagesFromString(String arg0) {
+      List<JSONObject> messages = new ArrayList<>();
+
       try {
         Object parsedArg0 = parser.parse(arg0);
-        if(parsedArg0 instanceof JSONObject) {
-          // if there is only one message
+        if (parsedArg0 instanceof JSONObject) {
+          // if the string only contains one message
           messages.add((JSONObject) parsedArg0);
 
-        } else if(parsedArg0 instanceof JSONArray) {
-          // there are multiple messages
+        } else if (parsedArg0 instanceof JSONArray) {
+          // if the string contains multiple messages
           JSONArray jsonArray = (JSONArray) parsedArg0;
-          for(Object json: jsonArray) {
-            if(json instanceof JSONObject) {
-              messages.add((JSONObject) json);
-
-            } else {
-              throw new IllegalArgumentException(format("invalid message: found '%s', expected JSONObject",
-                              ClassUtils.getShortClassName(json, "null")));
-            }
+          for (Object item : jsonArray) {
+            messages.addAll(getMessages(item));
           }
-        }
 
-      } catch(org.json.simple.parser.ParseException e) {
-        throw new IllegalArgumentException("invalid message", e);
-      }
-
-      // user must provide the stand alone profiler
-      StandAloneProfiler profiler = Util.getArg(1, StandAloneProfiler.class, args);
-      try {
-        for(JSONObject message : messages) {
-          profiler.apply(message);
+        } else {
+          throw new IllegalArgumentException(format("invalid message: found '%s', expected JSONObject or JSONArray",
+                  ClassUtils.getShortClassName(parsedArg0, "null")));
         }
 
-      } catch(ExecutionException e) {
-        throw new IllegalArgumentException(format("Failed to apply message; error=%s", e.getMessage()), e);
+      } catch (org.json.simple.parser.ParseException e) {
+        throw new IllegalArgumentException(format("invalid message: '%s'", e.getMessage()), e);
       }
 
-      return profiler;
+      return messages;
     }
   }
 

http://git-wip-us.apache.org/repos/asf/metron/blob/6ff39ae3/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java
----------------------------------------------------------------------
diff --git a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java
index bad3efe..e1c6aa8 100644
--- a/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java
+++ b/metron-analytics/metron-profiler-client/src/test/java/org/apache/metron/profiler/client/stellar/ProfilerFunctionsTest.java
@@ -21,13 +21,13 @@
 package org.apache.metron.profiler.client.stellar;
 
 import org.adrianwalker.multilinestring.Multiline;
-import org.apache.metron.profiler.ProfileMeasurement;
 import org.apache.metron.profiler.StandAloneProfiler;
 import org.apache.metron.stellar.common.DefaultStellarStatefulExecutor;
 import org.apache.metron.stellar.common.StellarStatefulExecutor;
-import org.apache.metron.stellar.common.shell.StellarExecutor;
 import org.apache.metron.stellar.dsl.Context;
 import org.apache.metron.stellar.dsl.functions.resolver.SimpleFunctionResolver;
+import org.json.simple.JSONObject;
+import org.json.simple.parser.JSONParser;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -176,7 +176,7 @@ public class ProfilerFunctionsTest {
   }
 
   @Test
-  public void testProfilerApply() {
+  public void testProfilerApplyWithString() {
 
     // initialize the profiler
     state.put("config", helloWorldProfilerDef);
@@ -195,7 +195,28 @@ public class ProfilerFunctionsTest {
   }
 
   @Test
-  public void testProfilerApplyWithMultipleMessages() {
+  public void testProfilerApplyWithJSONObject() throws Exception {
+
+    // initialize the profiler
+    state.put("config", helloWorldProfilerDef);
+    StandAloneProfiler profiler = run("PROFILER_INIT(config)", StandAloneProfiler.class);
+    state.put("profiler", profiler);
+
+    // apply a message to the profiler
+    JSONParser parser = new JSONParser();
+    JSONObject jsonObject = (JSONObject) parser.parse(message);
+    state.put("jsonObj", jsonObject);
+    StandAloneProfiler result = run("PROFILER_APPLY(jsonObj, profiler)", StandAloneProfiler.class);
+
+    // validate
+    assertSame(profiler, result);
+    assertEquals(1, profiler.getProfileCount());
+    assertEquals(1, profiler.getMessageCount());
+    assertEquals(1, profiler.getRouteCount());
+  }
+
+  @Test
+  public void testProfilerApplyWithMultipleMessagesInJSONString() {
 
     // initialize the profiler
     state.put("config", helloWorldProfilerDef);
@@ -214,6 +235,26 @@ public class ProfilerFunctionsTest {
   }
 
   @Test
+  public void testProfilerApplyWithListOfMessages() {
+
+    // initialize the profiler
+    state.put("config", helloWorldProfilerDef);
+    StandAloneProfiler profiler = run("PROFILER_INIT(config)", StandAloneProfiler.class);
+    state.put("profiler", profiler);
+
+    // apply a message to the profiler
+    state.put("msg", message);
+    StandAloneProfiler result = run("PROFILER_APPLY([msg, msg, msg], profiler)", StandAloneProfiler.class);
+
+    // validate
+    assertSame(profiler, result);
+    assertEquals(1, profiler.getProfileCount());
+    assertEquals(3, profiler.getMessageCount());
+    assertEquals(3, profiler.getRouteCount());
+  }
+
+
+  @Test
   public void testProfilerApplyWithEmptyList() {
 
     // initialize the profiler
@@ -250,8 +291,8 @@ public class ProfilerFunctionsTest {
     StandAloneProfiler profiler = run("PROFILER_INIT(config)", StandAloneProfiler.class);
     state.put("profiler", profiler);
 
-    // there is no 'messages' variable
-    StandAloneProfiler result = run("PROFILER_APPLY(messages, profiler)", StandAloneProfiler.class);
+    // there is no 'messages' variable - should throw exception
+    run("PROFILER_APPLY(messages, profiler)", StandAloneProfiler.class);
   }
 
   @Test


[5/6] metron git commit: METRON-1153 HDFS HdfsWriter never recovers from exceptions closes apache/incubator-metron#741

Posted by ma...@apache.org.
METRON-1153 HDFS HdfsWriter never recovers from exceptions closes apache/incubator-metron#741


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/b0c6e68c
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/b0c6e68c
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/b0c6e68c

Branch: refs/heads/Metron_0.4.1
Commit: b0c6e68ce5a3e9caa12711cf76aed1776d3745db
Parents: ccb5a0b
Author: justinleet <ju...@gmail.com>
Authored: Fri Sep 8 20:30:02 2017 -0400
Committer: cstella <ce...@gmail.com>
Committed: Fri Sep 8 20:30:02 2017 -0400

----------------------------------------------------------------------
 .../metron/writer/hdfs/SourceHandler.java       | 21 ++++-
 .../metron/writer/hdfs/HdfsWriterTest.java      | 91 ++++++++++++++++++--
 2 files changed, 104 insertions(+), 8 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/b0c6e68c/metron-platform/metron-writer/src/main/java/org/apache/metron/writer/hdfs/SourceHandler.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-writer/src/main/java/org/apache/metron/writer/hdfs/SourceHandler.java b/metron-platform/metron-writer/src/main/java/org/apache/metron/writer/hdfs/SourceHandler.java
index fbb5561..b841249 100644
--- a/metron-platform/metron-writer/src/main/java/org/apache/metron/writer/hdfs/SourceHandler.java
+++ b/metron-platform/metron-writer/src/main/java/org/apache/metron/writer/hdfs/SourceHandler.java
@@ -64,6 +64,7 @@ public class SourceHandler {
     this.rotationPolicy = rotationPolicy;
     this.syncPolicy = syncPolicy;
     this.fileNameFormat = fileNameFormat;
+    this.cleanupCallback = cleanupCallback;
     initialize();
   }
 
@@ -71,12 +72,26 @@ public class SourceHandler {
   protected void handle(JSONObject message, String sensor, WriterConfiguration config, SyncPolicyCreator syncPolicyCreator) throws IOException {
     byte[] bytes = (message.toJSONString() + "\n").getBytes();
     synchronized (this.writeLock) {
-      out.write(bytes);
+      try {
+        out.write(bytes);
+      } catch (IOException writeException) {
+        LOG.warn("IOException while writing output", writeException);
+        // If the stream is closed, attempt to rotate the file and try again, hoping it's transient
+        if (writeException.getMessage().contains("Stream Closed")) {
+          LOG.warn("Output Stream was closed. Attempting to rotate file and continue");
+          rotateOutputFile();
+          // If this write fails, the exception will be allowed to bubble up.
+          out.write(bytes);
+        } else {
+          throw writeException;
+        }
+      }
       this.offset += bytes.length;
 
       if (this.syncPolicy.mark(null, this.offset)) {
         if (this.out instanceof HdfsDataOutputStream) {
-          ((HdfsDataOutputStream) this.out).hsync(EnumSet.of(HdfsDataOutputStream.SyncFlag.UPDATE_LENGTH));
+          ((HdfsDataOutputStream) this.out)
+              .hsync(EnumSet.of(HdfsDataOutputStream.SyncFlag.UPDATE_LENGTH));
         } else {
           this.out.hsync();
         }
@@ -146,7 +161,7 @@ public class SourceHandler {
     return path;
   }
 
-  private void closeOutputFile() throws IOException {
+  protected void closeOutputFile() throws IOException {
     this.out.close();
   }
 

http://git-wip-us.apache.org/repos/asf/metron/blob/b0c6e68c/metron-platform/metron-writer/src/test/java/org/apache/metron/writer/hdfs/HdfsWriterTest.java
----------------------------------------------------------------------
diff --git a/metron-platform/metron-writer/src/test/java/org/apache/metron/writer/hdfs/HdfsWriterTest.java b/metron-platform/metron-writer/src/test/java/org/apache/metron/writer/hdfs/HdfsWriterTest.java
index 0118a15..832f8bf 100644
--- a/metron-platform/metron-writer/src/test/java/org/apache/metron/writer/hdfs/HdfsWriterTest.java
+++ b/metron-platform/metron-writer/src/test/java/org/apache/metron/writer/hdfs/HdfsWriterTest.java
@@ -18,11 +18,21 @@
 
 package org.apache.metron.writer.hdfs;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
 import org.apache.metron.common.configuration.IndexingConfigurations;
 import org.apache.metron.common.configuration.writer.IndexingWriterConfiguration;
 import org.apache.metron.common.configuration.writer.WriterConfiguration;
 import org.apache.storm.hdfs.bolt.format.DefaultFileNameFormat;
 import org.apache.storm.hdfs.bolt.format.FileNameFormat;
+import org.apache.storm.hdfs.bolt.sync.CountSyncPolicy;
+import org.apache.storm.hdfs.bolt.sync.SyncPolicy;
 import org.apache.storm.task.TopologyContext;
 import org.apache.storm.tuple.Tuple;
 import org.json.simple.JSONObject;
@@ -32,11 +42,6 @@ import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 
-import java.io.File;
-import java.io.IOException;
-import java.nio.file.Files;
-import java.util.*;
-
 // Suppress ConstantConditions to avoid NPE warnings that only would occur on test failure anyway
 @SuppressWarnings("ConstantConditions")
 public class HdfsWriterTest {
@@ -410,6 +415,82 @@ public class HdfsWriterTest {
     }
   }
 
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testSingleFileIfNoStreamClosed() throws Exception {
+    String function = "FORMAT('test-%s/%s', test.key, test.key)";
+    WriterConfiguration config = buildWriterConfiguration(function);
+    HdfsWriter writer = new HdfsWriter().withFileNameFormat(testFormat);
+    writer.init(new HashMap<String, String>(), createTopologyContext(), config);
+
+    JSONObject message = new JSONObject();
+    message.put("test.key", "test.value");
+    ArrayList<JSONObject> messages = new ArrayList<>();
+    messages.add(message);
+    ArrayList<Tuple> tuples = new ArrayList<>();
+
+    CountSyncPolicy basePolicy = new CountSyncPolicy(5);
+    ClonedSyncPolicyCreator creator = new ClonedSyncPolicyCreator(basePolicy);
+
+    writer.write(SENSOR_NAME, config, tuples, messages);
+    writer.write(SENSOR_NAME, config, tuples, messages);
+    writer.close();
+
+    File outputFolder = new File(folder.getAbsolutePath() + "/test-test.value/test.value/");
+
+    // The message should show up twice, once in each file
+    ArrayList<String> expected = new ArrayList<>();
+    expected.add(message.toJSONString());
+    expected.add(message.toJSONString());
+
+    // Assert both messages are in the same file, because the stream stayed open
+    Assert.assertEquals(1, outputFolder.listFiles().length);
+    for (File file : outputFolder.listFiles()) {
+      List<String> lines = Files.readAllLines(file.toPath());
+      // One line per file
+      Assert.assertEquals(2, lines.size());
+      Assert.assertEquals(expected, lines);
+    }
+  }
+
+  @Test
+  @SuppressWarnings("unchecked")
+  public void testHandleAttemptsRotateIfStreamClosed() throws Exception {
+    String function = "FORMAT('test-%s/%s', test.key, test.key)";
+    WriterConfiguration config = buildWriterConfiguration(function);
+    HdfsWriter writer = new HdfsWriter().withFileNameFormat(testFormat);
+    writer.init(new HashMap<String, String>(), createTopologyContext(), config);
+
+    JSONObject message = new JSONObject();
+    message.put("test.key", "test.value");
+    ArrayList<JSONObject> messages = new ArrayList<>();
+    messages.add(message);
+    ArrayList<Tuple> tuples = new ArrayList<>();
+
+    CountSyncPolicy basePolicy = new CountSyncPolicy(5);
+    ClonedSyncPolicyCreator creator = new ClonedSyncPolicyCreator(basePolicy);
+
+    writer.write(SENSOR_NAME, config, tuples, messages);
+    writer.getSourceHandler(SENSOR_NAME, "test-test.value/test.value", config).closeOutputFile();
+    writer.getSourceHandler(SENSOR_NAME, "test-test.value/test.value", config).handle(message, SENSOR_NAME, config, creator);
+    writer.close();
+
+    File outputFolder = new File(folder.getAbsolutePath() + "/test-test.value/test.value/");
+
+    // The message should show up twice, once in each file
+    ArrayList<String> expected = new ArrayList<>();
+    expected.add(message.toJSONString());
+
+    // Assert this went into a new file because it actually rotated
+    Assert.assertEquals(2, outputFolder.listFiles().length);
+    for (File file : outputFolder.listFiles()) {
+      List<String> lines = Files.readAllLines(file.toPath());
+      // One line per file
+      Assert.assertEquals(1, lines.size());
+      Assert.assertEquals(expected, lines);
+    }
+  }
+
   protected WriterConfiguration buildWriterConfiguration(String function) {
     IndexingConfigurations indexingConfig = new IndexingConfigurations();
     Map<String, Object> sensorIndexingConfig = new HashMap<>();


[4/6] metron git commit: METRON-1163 RAT failures for metron-interface/metron-alerts closes apache/incubator-metron#743

Posted by ma...@apache.org.
METRON-1163 RAT failures for metron-interface/metron-alerts closes apache/incubator-metron#743


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/ccb5a0bd
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/ccb5a0bd
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/ccb5a0bd

Branch: refs/heads/Metron_0.4.1
Commit: ccb5a0bdd4cb7d04c0d1f23359215ffb643774b5
Parents: 7768ff6
Author: mattf-horton <mf...@hortonworks.com>
Authored: Fri Sep 8 20:27:32 2017 -0400
Committer: cstella <ce...@gmail.com>
Committed: Fri Sep 8 20:27:32 2017 -0400

----------------------------------------------------------------------
 pom.xml | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/ccb5a0bd/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index ad97f58..6e92772 100644
--- a/pom.xml
+++ b/pom.xml
@@ -341,8 +341,12 @@
                         <!-- ACE editor assets are covered in the metron-config NOTICE file -->
                         <exclude>**/src/assets/ace/**</exclude>
                         <exclude>dist/assets/ace/**</exclude>
-                        <!-- Generated svg containing Font Awesome fonts are covered in the metron-config README and NOTICE file -->
+                        <!-- Generated svg and bundle.css containing Font Awesome fonts are covered in the
+                             metron-interface/metron-config README and NOTICE files -->
                         <exclude>dist/*.svg</exclude>
+                        <exclude>dist/styles.a0b6b99c10d9a13dc67e.bundle.css</exclude>
+                        <!-- 3rdpartylicenses.txt is an empty file carried along by imported libraries -->
+                        <exclude>dist/3rdpartylicenses.txt</exclude>
 
                         <exclude>e2e/*.js.map</exclude>
                         <!-- Checkstyle is LGPL.  We derive ours from their base, but don't ship it, so it's fine use.


[3/6] metron git commit: METRON-1168: Add SUBSTRING method to stellar this closes apache/incubator-metron#742

Posted by ma...@apache.org.
METRON-1168: Add SUBSTRING method to stellar this closes apache/incubator-metron#742


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/7768ff67
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/7768ff67
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/7768ff67

Branch: refs/heads/Metron_0.4.1
Commit: 7768ff673cb4a7a62180d16fdb92dc0f4123f4f1
Parents: ea65a37
Author: cstella <ce...@gmail.com>
Authored: Fri Sep 8 20:26:06 2017 -0400
Committer: cstella <ce...@gmail.com>
Committed: Fri Sep 8 20:26:06 2017 -0400

----------------------------------------------------------------------
 metron-stellar/stellar-common/README.md         | 47 ++++++++++++--------
 .../stellar/dsl/functions/StringFunctions.java  | 40 +++++++++++++++++
 .../dsl/functions/StringFunctionsTest.java      | 17 +++++++
 3 files changed, 85 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/7768ff67/metron-stellar/stellar-common/README.md
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/README.md b/metron-stellar/stellar-common/README.md
index 340a7ae..a070c13 100644
--- a/metron-stellar/stellar-common/README.md
+++ b/metron-stellar/stellar-common/README.md
@@ -110,8 +110,8 @@ In the core language functions, we support basic functional programming primitiv
 | [ `BLOOM_EXISTS`](#bloom_exists)                                                                   |
 | [ `BLOOM_INIT`](#bloom_init)                                                                       |
 | [ `BLOOM_MERGE`](#bloom_merge)                                                                     |
-| [ `CEILING`](#ceiling)                                                           |
-| [ `COS`](#cos)                                                                   |
+| [ `CEILING`](#ceiling)                                                                             |
+| [ `COS`](#cos)                                                                                     |
 | [ `CHOP`](#chop)                                                                                   |
 | [ `CHOMP`](#chomp)                                                                                 |
 | [ `COUNT_MATCHES`](#count_matches)                                                                 |
@@ -126,13 +126,13 @@ In the core language functions, we support basic functional programming primitiv
 | [ `ENDS_WITH`](#ends_with)                                                                         |
 | [ `ENRICHMENT_EXISTS`](#enrichment_exists)                                                         |
 | [ `ENRICHMENT_GET`](#enrichment_get)                                                               |
-| [ `EXP`](#exp)                                                                   |
+| [ `EXP`](#exp)                                                                                     |
 | [ `FILL_LEFT`](#fill_left)                                                                         |
 | [ `FILL_RIGHT`](#fill_right)                                                                       |
 | [ `FILTER`](#filter)                                                                               |
-| [ `FLOOR`](#floor)                                                               |
-| [ `FUZZY_LANGS`](#fuzzy_langs)                                                   |
-| [ `FUZZY_SCORE`](#fuzzy_score)                                                   |
+| [ `FLOOR`](#floor)                                                                                 |
+| [ `FUZZY_LANGS`](#fuzzy_langs)                                                                     |
+| [ `FUZZY_SCORE`](#fuzzy_score)                                                                     |
 | [ `FORMAT`](#format)                                                                               |
 | [ `GEO_GET`](#geo_get)                                                                             |
 | [ `GEOHASH_CENTROID`](#geohash_centroid)                                                           |
@@ -144,8 +144,8 @@ In the core language functions, we support basic functional programming primitiv
 | [ `GET`](#get)                                                                                     |
 | [ `GET_FIRST`](#get_first)                                                                         |
 | [ `GET_LAST`](#get_last)                                                                           |
-| [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings)                                           |
-| [ `HASH`](#hash)                                                                           |
+| [ `GET_SUPPORTED_ENCODINGS`](#get_supported_encodings)                                             |
+| [ `HASH`](#hash)                                                                                   |
 | [ `HLLP_CARDINALITY`](../../metron-analytics/metron-statistics#hllp_cardinality)                   |
 | [ `HLLP_INIT`](../../metron-analytics/metron-statistics#hllp_init)                                 |
 | [ `HLLP_MERGE`](../../metron-analytics/metron-statistics#hllp_merge)                               |
@@ -166,9 +166,9 @@ In the core language functions, we support basic functional programming primitiv
 | [ `KAFKA_TAIL`](#kafka_tail)                                                                       |
 | [ `LENGTH`](#length)                                                                               |
 | [ `LIST_ADD`](#list_add)                                                                           |
-| [ `LOG2`](#log2)                                                                               |
-| [ `LOG10`](#log10)                                                                               |
-| [ `LN`](#ln)                                                                               |
+| [ `LOG2`](#log2)                                                                                   |
+| [ `LOG10`](#log10)                                                                                 |
+| [ `LN`](#ln)                                                                                       |
 | [ `MAAS_GET_ENDPOINT`](#maas_get_endpoint)                                                         |
 | [ `MAAS_MODEL_APPLY`](#maas_model_apply)                                                           |
 | [ `MAP`](#map)                                                                                     |
@@ -186,15 +186,15 @@ In the core language functions, we support basic functional programming primitiv
 | [ `PROTOCOL_TO_NAME`](#protocol_to_name)                                                           |
 | [ `REDUCE`](#reduce)                                                                               |
 | [ `REGEXP_MATCH`](#regexp_match)                                                                   |
-| [ `REGEXP_GROUP_VAL`](#regexp_group_val)                                                                   |
-| [ `ROUND`](#round)                                                                   |
-| [ `SET_ADD`](#set_add)                                                                            |
+| [ `REGEXP_GROUP_VAL`](#regexp_group_val)                                                           |
+| [ `ROUND`](#round)                                                                                 |
+| [ `SET_ADD`](#set_add)                                                                             |
 | [ `SET_INIT`](#set_init)                                                                           |
 | [ `SET_MERGE`](#set_merge)                                                                         |
 | [ `SET_REMOVE`](#set_remove)                                                                       |
 | [ `SPLIT`](#split)                                                                                 |
-| [ `SIN`](#sin)                                                                                 |
-| [ `SQRT`](#sqrt)                                                                                 |
+| [ `SIN`](#sin)                                                                                     |
+| [ `SQRT`](#sqrt)                                                                                   |
 | [ `STARTS_WITH`](#starts_with)                                                                     |
 | [ `STATS_ADD`](../../metron-analytics/metron-statistics#stats_add)                                 |
 | [ `STATS_BIN`](../../metron-analytics/metron-statistics#stats_bin)                                 |
@@ -216,9 +216,10 @@ In the core language functions, we support basic functional programming primitiv
 | [ `STATS_SUM_SQUARES`](../../metron-analytics/metron-statistics#stats_sum_squares)                 |
 | [ `STATS_VARIANCE`](../../metron-analytics/metron-statistics#stats_variance)                       |
 | [ `STRING_ENTROPY`](#string_entropy)                                                               |
+| [ `SUBSTRING`](#substring)                                                                         |
 | [ `SYSTEM_ENV_GET`](#system_env_get)                                                               |
 | [ `SYSTEM_PROPERTY_GET`](#system_property_get)                                                     |
-| [ `TAN`](#tan)                                                                         |
+| [ `TAN`](#tan)                                                                                     |
 | [ `TO_DOUBLE`](#to_double)                                                                         |
 | [ `TO_EPOCH_TIMESTAMP`](#to_epoch_timestamp)                                                       |
 | [ `TO_FLOAT`](#to_float)                                                                           |
@@ -235,8 +236,8 @@ In the core language functions, we support basic functional programming primitiv
 | [ `WEEK_OF_MONTH`](#week_of_month)                                                                 |
 | [ `WEEK_OF_YEAR`](#week_of_year)                                                                   |
 | [ `YEAR`](#year)                                                                                   |
-| [ `ZIP`](#zip)                                                                                   |
-| [ `ZIP_JAGGED`](#zip_jagged)                                                                                   |
+| [ `ZIP`](#zip)                                                                                     |
+| [ `ZIP_JAGGED`](#zip_jagged)                                                                       |
 
 ### `APPEND_IF_MISSING`
   * Description: Appends the suffix to the end of the string if the string does not already end with any of the suffixes.
@@ -869,6 +870,14 @@ In the core language functions, we support basic functional programming primitiv
     * key - Property to get the value for
   * Returns: String
 
+### `SUBSTRING`
+  * Description: Returns the substring of a string
+  * Input:
+    * input - The string to take the substring of
+    * start - The starting position (`0`-based and inclusive)
+    * end? - The ending position (`0`-based and exclusive)
+  * Returns: The substring of the input
+
 ### `TAN`
   * Description: Returns the tangent of a number.
   * Input:

http://git-wip-us.apache.org/repos/asf/metron/blob/7768ff67/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/StringFunctions.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/StringFunctions.java b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/StringFunctions.java
index 289fa7f..99c8fe7 100644
--- a/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/StringFunctions.java
+++ b/metron-stellar/stellar-common/src/main/java/org/apache/metron/stellar/dsl/functions/StringFunctions.java
@@ -321,6 +321,46 @@ public class StringFunctions {
     }
   }
 
+  @Stellar( name="SUBSTRING"
+          , description = "Returns a substring of a string"
+          , params = {
+                "input - The string to take the substring of",
+                "start - The starting position (0-based and inclusive)",
+                "end? - The ending position (0-based and exclusive)"
+                     }
+          , returns = "The substring of the input"
+  )
+  public static class Substring extends BaseStellarFunction {
+
+    @Override
+    public Object apply(List<Object> strings) {
+
+      if(strings == null || strings.size() < 2 ) {
+        throw new IllegalArgumentException("[SUBSTRING] required 2 arguments: the input and the start position (inclusive)");
+      }
+      String var = strings.get(0) == null?null: (String) strings.get(0);
+      Integer start = strings.get(1) == null?null:(Integer)strings.get(1);
+      Integer end = null;
+      if(strings.size() > 2) {
+         end = strings.get(2) == null ? null : (Integer) strings.get(2);
+      }
+      if(var == null || start == null) {
+        return null;
+      }
+      else if(var.length() == 0) {
+        return var;
+      }
+      else {
+        if(end == null) {
+          return var.substring(start);
+        }
+        else {
+          return var.substring(start, end);
+        }
+      }
+    }
+  }
+
   @Stellar( name="CHOMP"
           , description = "Removes one newline from end of a String if it's there, otherwise leave it alone. A newline is \"\\n\", \"\\r\", or \"\\r\\n\""
           , params = { "the String to chomp a newline from, may be null"}

http://git-wip-us.apache.org/repos/asf/metron/blob/7768ff67/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/StringFunctionsTest.java
----------------------------------------------------------------------
diff --git a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/StringFunctionsTest.java b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/StringFunctionsTest.java
index 858a043..2b1115e 100644
--- a/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/StringFunctionsTest.java
+++ b/metron-stellar/stellar-common/src/test/java/org/apache/metron/stellar/dsl/functions/StringFunctionsTest.java
@@ -408,6 +408,23 @@ public class StringFunctionsTest {
 
   }
 
+  @Test
+  public void testSubstring() throws Exception {
+    Map<String, Object> variables = ImmutableMap.of("s", "apache metron");
+    Assert.assertEquals("metron", run("SUBSTRING(s, 7)", variables));
+    Assert.assertEquals("me", run("SUBSTRING(s, 7, 9)", variables));
+    Assert.assertNull(run("SUBSTRING(null, 7, 9)", new HashMap<>()));
+    Assert.assertNull(run("SUBSTRING(null, null, 9)", new HashMap<>()));
+    Assert.assertNull(run("SUBSTRING(s, null, 9)", variables));
+    Assert.assertNull(run("SUBSTRING(null, null, null)", new HashMap<>()));
+    Assert.assertEquals("metron", run("SUBSTRING(s, 7, null)", variables));
+  }
+
+  @Test(expected=ParseException.class)
+  public void testSubstring_invalidEmpty() throws Exception {
+    Assert.assertEquals("metron", (String) run("SUBSTRING()", new HashMap<>()));
+  }
+
   /**
    * COUNT_MATCHES StringFunction
    */


[6/6] metron git commit: METRON-1169: dependency checker has not been running in travis closes apache/incubator-metron#744

Posted by ma...@apache.org.
METRON-1169: dependency checker has not been running in travis closes apache/incubator-metron#744


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/269d42e9
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/269d42e9
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/269d42e9

Branch: refs/heads/Metron_0.4.1
Commit: 269d42e923c23835871c9bbc23c4ab0c6007abc4
Parents: b0c6e68
Author: cstella <ce...@gmail.com>
Authored: Fri Sep 8 21:30:03 2017 -0400
Committer: cstella <ce...@gmail.com>
Committed: Fri Sep 8 21:30:03 2017 -0400

----------------------------------------------------------------------
 .travis.yml               | 3 +--
 dependencies_with_url.csv | 2 ++
 2 files changed, 3 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/269d42e9/.travis.yml
----------------------------------------------------------------------
diff --git a/.travis.yml b/.travis.yml
index 917b184..f5edfb2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -31,13 +31,12 @@ before_install:
   - export PATH=$M2_HOME/bin:$PATH
   - npm config set cache $HOME/.npm-cache --global
   - npm config set prefix $HOME/.npm-prefix --global
-  - time build_utils/verify_licenses.sh
 
 install:
   - time mvn -q -T 2C -DskipTests clean install
 
 script:
-  - time mvn -q -T 2C surefire:test@unit-tests && time mvn -q surefire:test@integration-tests && time mvn -q test --projects metron-interface/metron-config
+  - time mvn -q -T 2C surefire:test@unit-tests && time mvn -q surefire:test@integration-tests && time mvn -q test --projects metron-interface/metron-config && time build_utils/verify_licenses.sh
 
 before_cache:
   - rm -rf $HOME/.m2/repository/org/apache/metron

http://git-wip-us.apache.org/repos/asf/metron/blob/269d42e9/dependencies_with_url.csv
----------------------------------------------------------------------
diff --git a/dependencies_with_url.csv b/dependencies_with_url.csv
index d09fed6..9ebb9e4 100644
--- a/dependencies_with_url.csv
+++ b/dependencies_with_url.csv
@@ -307,3 +307,5 @@ net.byteseek:byteseek:jar:2.0.3:compile,BSD,https://github.com/nishihatapalmer/b
 org.springframework.security.kerberos:spring-security-kerberos-client:jar:1.0.1.RELEASE:compile,ASLv2,https://github.com/spring-projects/spring-security-kerberos
 org.springframework.security.kerberos:spring-security-kerberos-core:jar:1.0.1.RELEASE:compile,ASLv2,https://github.com/spring-projects/spring-security-kerberos
 org.springframework.kafka:spring-kafka:jar:1.1.1.RELEASE:compile,ASLv2,https://github.com/spring-projects/spring-kafka
+ch.hsr:geohash:jar:1.3.0:compile,ASLv2,https://github.com/kungfoo/geohash-java
+org.locationtech.spatial4j:spatial4j:jar:0.6:compile,ASLv2,https://github.com/locationtech/spatial4j


[2/6] metron git commit: METRON-1077 Use column meta data end point in alerts ui (iraghumitra via merrimanr) closes apache/metron#700

Posted by ma...@apache.org.
METRON-1077 Use column meta data end point in alerts ui (iraghumitra via merrimanr) closes apache/metron#700


Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/ea65a37c
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/ea65a37c
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/ea65a37c

Branch: refs/heads/Metron_0.4.1
Commit: ea65a37c04c2e0d8fad1f1ea024af39ae56049ca
Parents: 6ff39ae
Author: iraghumitra <ra...@gmail.com>
Authored: Fri Sep 8 17:56:39 2017 -0500
Committer: merrimanr <me...@apache.org>
Committed: Fri Sep 8 17:56:39 2017 -0500

----------------------------------------------------------------------
 .../metron-alerts/alerts-server-e2e.js          |  20 ++--
 .../metron-alerts/scripts/alerts-server.js      |  14 +--
 .../alert-details/alert-details.component.ts    |  16 +--
 .../alerts/alerts-list/alerts-list.component.ts |  26 ++---
 .../alerts/alerts-list/alerts-list.module.ts    |   4 +-
 .../configure-table.component.ts                |  10 +-
 .../metron-alerts/src/app/app.module.ts         |   4 +-
 .../src/app/model/alerts-search-response.ts     |  23 ----
 .../src/app/model/search-request.ts             |   3 +-
 .../src/app/model/search-response.ts            |  23 ++++
 .../src/app/service/alert.service.ts            |  72 ------------
 .../src/app/service/cluster-metadata.service.ts |   7 +-
 .../src/app/service/data-source.ts              |   4 +-
 .../service/elasticsearch-localstorage-impl.ts  |   4 +-
 .../src/app/service/rest-api-impl.ts            |  46 --------
 .../src/app/service/search.service.ts           | 112 +++++++++++++++++++
 .../metron-alerts/src/app/utils/constants.ts    |   2 +
 .../src/app/utils/elasticsearch-utils.ts        |   6 +-
 18 files changed, 196 insertions(+), 200 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/alerts-server-e2e.js
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/alerts-server-e2e.js b/metron-interface/metron-alerts/alerts-server-e2e.js
index 2a5f80b..f1b6410 100644
--- a/metron-interface/metron-alerts/alerts-server-e2e.js
+++ b/metron-interface/metron-alerts/alerts-server-e2e.js
@@ -30,7 +30,7 @@ var favicon     = require('serve-favicon');
 var proxy       = require('http-proxy-middleware');
 var argv        = require('optimist')
                   .demand(['p', 'r'])
-                  .usage('Usage: server.js -p [port]')
+                  .usage('Usage: alerts-server-e2e.js -p [port]')
                   .describe('p', 'Port to run metron alerts ui')
                   .describe('r', 'Url where metron rest application is available')
                   .argv;
@@ -40,7 +40,7 @@ var metronUIAddress = '';
 var ifaces = os.networkInterfaces();
 var restUrl =  argv.r || argv.resturl;
 var conf = {
-  "elastic": {
+  "restapi": {
     "target": restUrl,
     "secure": false
   }
@@ -134,24 +134,28 @@ var clusterState = function(req, res){
 
 
 app.use(compression());
-app.use(bodyParser.json());
+
 app.use(favicon(path.join(__dirname, 'dist/favicon.ico')));
 app.use(serveStatic(path.join(__dirname, 'dist'), {
   maxAge: '1d',
   setHeaders: setCustomCacheControl
 }));
 
-app.use('/api/v1/user', proxy(conf.elastic));
-app.use('/logout', proxy(conf.elastic));
-app.post('/api/v1/search/search', searchResult);
-app.use('/_cluster', clusterState);
+app.use('/logout', proxy(conf.restapi));
+app.use('/api/v1/user', proxy(conf.restapi));
+app.use('/api/v1/search/findOne', proxy(conf.restapi));
+app.use('/api/v1/search/column/metadata', proxy(conf.restapi));
+
 app.get('/alerts-list', indexHTML);
 app.get('', indexHTML);
+
+app.use(bodyParser.json());
+app.post('/api/v1/search/search', searchResult);
+
 app.use(function(req, res, next){
   res.status(404).sendStatus(304);
 });
 
-
 app.listen(port, function(){
   console.log("Metron alerts ui is listening on " + metronUIAddress);
 });

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/scripts/alerts-server.js
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/scripts/alerts-server.js b/metron-interface/metron-alerts/scripts/alerts-server.js
index 6fb35c9..6a999f2 100644
--- a/metron-interface/metron-alerts/scripts/alerts-server.js
+++ b/metron-interface/metron-alerts/scripts/alerts-server.js
@@ -22,15 +22,13 @@
 var os          = require('os');
 var app         = require('express')();
 var path        = require('path');
-var compression = require('compression')
+var compression = require('compression');
 var serveStatic = require('serve-static');
 var favicon     = require('serve-favicon');
 var proxy       = require('http-proxy-middleware');
 var argv        = require('optimist')
-                  .demand(['p', 'r', 'e'])
-                  .alias('r', 'resturl')
-                  .alias('e', 'elasticurl')
-                  .usage('Usage: server.js -p [port] -r [restUrl] -e [elasticURL]')
+                  .demand(['p', 'r'])
+                  .usage('Usage: alert-server.js -p [port] -r [restUrl]')
                   .describe('p', 'Port to run metron management ui')
                   .describe('r', 'Url where metron rest application is available')
                   .argv;
@@ -39,12 +37,7 @@ var port = argv.p;
 var metronUIAddress = '';
 var ifaces = os.networkInterfaces();
 var restUrl =  argv.r || argv.resturl;
-var elasticUrl =  argv.e || argv.elasticurl;
 var conf = {
-  "elastic": {
-    "target": elasticUrl,
-    "secure": false
-  },
   "rest": {
     "target": restUrl,
     "secure": false
@@ -78,7 +71,6 @@ var rewriteSearchProxy = proxy({
 app.use(compression());
 
 app.use('/api', proxy(conf.rest));
-app.use('/_cluster', proxy(conf.elastic));
 
 app.use(favicon(path.join(__dirname, '../alerts-ui/favicon.ico')));
 

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
index 915c0c1..2e7884e 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alert-details/alert-details.component.ts
@@ -17,7 +17,7 @@
  */
 import { Component, OnInit } from '@angular/core';
 import {Router, ActivatedRoute} from '@angular/router';
-import {AlertService} from '../../service/alert.service';
+import {SearchService} from '../../service/search.service';
 import {Alert} from '../../model/alert';
 import {WorkflowService} from '../../service/workflow.service';
 import {AlertSource} from '../../model/alert-source';
@@ -42,7 +42,7 @@ export class AlertDetailsComponent implements OnInit {
 
   constructor(private router: Router,
               private activatedRoute: ActivatedRoute,
-              private alertsService: AlertService,
+              private searchService: SearchService,
               private workflowService: WorkflowService) { }
 
   goBack() {
@@ -51,7 +51,7 @@ export class AlertDetailsComponent implements OnInit {
   }
 
   getData() {
-    this.alertsService.getAlert(this.alertSourceType, this.alertId).subscribe(alert => {
+    this.searchService.getAlert(this.alertSourceType, this.alertId).subscribe(alert => {
       this.alertSource = alert;
       this.alertFields = Object.keys(alert).filter(field => !field.includes(':ts') && field !== 'original_string').sort();
     });
@@ -70,7 +70,7 @@ export class AlertDetailsComponent implements OnInit {
     tAlert.source = this.alertSource;
 
     this.selectedAlertState = AlertState.OPEN;
-    this.alertsService.updateAlertState([tAlert], 'OPEN', '').subscribe(results => {
+    this.searchService.updateAlertState([tAlert], 'OPEN', '').subscribe(results => {
       this.getData();
     });
   }
@@ -80,7 +80,7 @@ export class AlertDetailsComponent implements OnInit {
     tAlert.source = this.alertSource;
 
     this.selectedAlertState = AlertState.NEW;
-    this.alertsService.updateAlertState([tAlert], 'NEW', '').subscribe(results => {
+    this.searchService.updateAlertState([tAlert], 'NEW', '').subscribe(results => {
       this.getData();
     });
   }
@@ -91,7 +91,7 @@ export class AlertDetailsComponent implements OnInit {
 
     this.selectedAlertState = AlertState.ESCALATE;
     this.workflowService.start([tAlert]).subscribe(workflowId => {
-      this.alertsService.updateAlertState([tAlert], 'ESCALATE', workflowId).subscribe(results => {
+      this.searchService.updateAlertState([tAlert], 'ESCALATE', workflowId).subscribe(results => {
         this.getData();
       });
     });
@@ -102,7 +102,7 @@ export class AlertDetailsComponent implements OnInit {
     tAlert.source = this.alertSource;
 
     this.selectedAlertState = AlertState.DISMISS;
-    this.alertsService.updateAlertState([tAlert], 'DISMISS', '').subscribe(results => {
+    this.searchService.updateAlertState([tAlert], 'DISMISS', '').subscribe(results => {
       this.getData();
     });
   }
@@ -112,7 +112,7 @@ export class AlertDetailsComponent implements OnInit {
     tAlert.source = this.alertSource;
 
     this.selectedAlertState = AlertState.RESOLVE;
-    this.alertsService.updateAlertState([tAlert], 'RESOLVE', '').subscribe(results => {
+    this.searchService.updateAlertState([tAlert], 'RESOLVE', '').subscribe(results => {
       this.getData();
     });
   }

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
index 35cbeff..72046fc 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.component.ts
@@ -20,7 +20,7 @@ import {Router, NavigationStart} from '@angular/router';
 import {Observable, Subscription} from 'rxjs/Rx';
 
 import {Alert} from '../../model/alert';
-import {AlertService} from '../../service/alert.service';
+import {SearchService} from '../../service/search.service';
 import {QueryBuilder} from './query-builder';
 import {ConfigureTableService} from '../../service/configure-table.service';
 import {WorkflowService} from '../../service/workflow.service';
@@ -35,7 +35,7 @@ import {SaveSearch} from '../../model/save-search';
 import {TableMetadata} from '../../model/table-metadata';
 import {MetronDialogBox, DialogType} from '../../shared/metron-dialog-box';
 import {AlertSearchDirective} from '../../shared/directives/alert-search.directive';
-import {AlertsSearchResponse} from '../../model/alerts-search-response';
+import {SearchResponse} from '../../model/search-response';
 import {ElasticsearchUtils} from '../../utils/elasticsearch-utils';
 
 @Component({
@@ -65,7 +65,7 @@ export class AlertsListComponent implements OnInit, OnDestroy {
   queryBuilder: QueryBuilder = new QueryBuilder();
 
   constructor(private router: Router,
-              private alertsService: AlertService,
+              private searchService: SearchService,
               private configureTableService: ConfigureTableService,
               private workflowService: WorkflowService,
               private clusterMetaDataService: ClusterMetaDataService,
@@ -204,7 +204,7 @@ export class AlertsListComponent implements OnInit, OnDestroy {
   }
 
   onConfigRowsChange() {
-    this.alertsService.interval = this.refreshInterval;
+    this.searchService.interval = this.refreshInterval;
     this.search();
   }
 
@@ -253,26 +253,26 @@ export class AlertsListComponent implements OnInit, OnDestroy {
 
   processEscalate() {
     this.workflowService.start(this.selectedAlerts).subscribe(workflowId => {
-      this.alertsService.updateAlertState(this.selectedAlerts, 'ESCALATE', workflowId).subscribe(results => {
+      this.searchService.updateAlertState(this.selectedAlerts, 'ESCALATE', workflowId).subscribe(results => {
         this.updateSelectedAlertStatus('ESCALATE');
       });
     });
   }
 
   processDismiss() {
-    this.alertsService.updateAlertState(this.selectedAlerts, 'DISMISS', '').subscribe(results => {
+    this.searchService.updateAlertState(this.selectedAlerts, 'DISMISS', '').subscribe(results => {
       this.updateSelectedAlertStatus('DISMISS');
     });
   }
 
   processOpen() {
-    this.alertsService.updateAlertState(this.selectedAlerts, 'OPEN', '').subscribe(results => {
+    this.searchService.updateAlertState(this.selectedAlerts, 'OPEN', '').subscribe(results => {
       this.updateSelectedAlertStatus('OPEN');
     });
   }
 
   processResolve() {
-    this.alertsService.updateAlertState(this.selectedAlerts, 'RESOLVE', '').subscribe(results => {
+    this.searchService.updateAlertState(this.selectedAlerts, 'RESOLVE', '').subscribe(results => {
       this.updateSelectedAlertStatus('RESOLVE');
     });
   }
@@ -313,10 +313,10 @@ export class AlertsListComponent implements OnInit, OnDestroy {
       this.saveSearchService.saveAsRecentSearches(savedSearch).subscribe(() => {});
     }
 
-    this.alertsService.search(this.queryBuilder.searchRequest).subscribe(results => {
+    this.searchService.search(this.queryBuilder.searchRequest).subscribe(results => {
       this.setData(results);
     }, error => {
-      this.setData(new AlertsSearchResponse());
+      this.setData(new SearchResponse());
       this.metronDialogBox.showConfirmationMessage(ElasticsearchUtils.extractESErrorMessage(error), DialogType.Error);
     });
 
@@ -331,7 +331,7 @@ export class AlertsListComponent implements OnInit, OnDestroy {
     }
   }
 
-  setData(results: AlertsSearchResponse) {
+  setData(results: SearchResponse) {
     this.alerts = results.results;
     this.pagingData.total = results.total;
   }
@@ -370,7 +370,7 @@ export class AlertsListComponent implements OnInit, OnDestroy {
   tryStartPolling() {
     if (!this.pauseRefresh) {
       this.tryStopPolling();
-      this.refreshTimer = this.alertsService.pollSearch(this.queryBuilder.searchRequest).subscribe(results => {
+      this.refreshTimer = this.searchService.pollSearch(this.queryBuilder.searchRequest).subscribe(results => {
         this.setData(results);
       });
     }
@@ -383,7 +383,7 @@ export class AlertsListComponent implements OnInit, OnDestroy {
   }
 
   updateConfigRowsSettings() {
-    this.alertsService.interval = this.refreshInterval;
+    this.searchService.interval = this.refreshInterval;
     this.queryBuilder.setFromAndSize(this.pagingData.from, this.pagingData.size);
   }
 

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.module.ts b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.module.ts
index adc8cbb..e6adae3 100644
--- a/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.module.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/alerts-list/alerts-list.module.ts
@@ -20,7 +20,7 @@ import {NgModule} from '@angular/core';
 import {AlertsListComponent}   from './alerts-list.component';
 import {routing} from './alerts-list.routing';
 import {SharedModule} from '../../shared/shared.module';
-import {AlertService} from '../../service/alert.service';
+import {SearchService} from '../../service/search.service';
 import {MetronSorterModule} from '../../shared/metron-table/metron-sorter/metron-sorter.module';
 import {ListGroupModule} from '../../shared/list-group/list-grup.module';
 import {CollapseModule} from '../../shared/collapse/collapse.module';
@@ -32,7 +32,7 @@ import {ConfigureRowsModule} from '../configure-rows/configure-rows.module';
                 ListGroupModule, CollapseModule],
     exports: [AlertsListComponent],
     declarations: [AlertsListComponent],
-    providers: [AlertService],
+    providers: [SearchService],
 })
 export class AlertsListModule {
 }

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
index 941343e..0c0117b 100644
--- a/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
+++ b/metron-interface/metron-alerts/src/app/alerts/configure-table/configure-table.component.ts
@@ -24,6 +24,7 @@ import {ClusterMetaDataService} from '../../service/cluster-metadata.service';
 import {ColumnMetadata} from '../../model/column-metadata';
 import {ColumnNamesService} from '../../service/column-names.service';
 import {ColumnNames} from '../../model/column-names';
+import {SearchService} from '../../service/search.service';
 
 export enum AlertState {
   NEW, OPEN, ESCALATE, DISMISS, RESOLVE
@@ -51,8 +52,11 @@ export class ConfigureTableComponent implements OnInit {
 
   allColumns: ColumnMetadataWrapper[] = [];
 
-  constructor(private router: Router, private activatedRoute: ActivatedRoute, private configureTableService: ConfigureTableService,
-              private clusterMetaDataService: ClusterMetaDataService, private columnNamesService: ColumnNamesService) { }
+  constructor(private router: Router, private activatedRoute: ActivatedRoute,
+              private configureTableService: ConfigureTableService,
+              private clusterMetaDataService: ClusterMetaDataService,
+              private columnNamesService: ColumnNamesService,
+              private searchService: SearchService) { }
 
   goBack() {
     this.router.navigateByUrl('/alerts-list');
@@ -80,7 +84,7 @@ export class ConfigureTableComponent implements OnInit {
   ngOnInit() {
     Observable.forkJoin(
       this.clusterMetaDataService.getDefaultColumns(),
-      this.clusterMetaDataService.getColumnMetaData(),
+      this.searchService.getColumnMetaData(),
       this.configureTableService.getTableMetadata()
     ).subscribe((response: any) => {
       this.prepareData(response[0], response[1], response[2].tableColumns);

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/app.module.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/app.module.ts b/metron-interface/metron-alerts/src/app/app.module.ts
index 295c748..f16b2d1 100644
--- a/metron-interface/metron-alerts/src/app/app.module.ts
+++ b/metron-interface/metron-alerts/src/app/app.module.ts
@@ -36,7 +36,7 @@ import {ConfigureRowsModule} from './alerts/configure-rows/configure-rows.module
 import {SwitchModule} from './shared/switch/switch.module';
 import {ColumnNamesService} from './service/column-names.service';
 import {DataSource} from './service/data-source';
-import {RestApiImpl} from './service/rest-api-impl';
+import {ElasticSearchLocalstorageImpl} from './service/elasticsearch-localstorage-impl';
 import {LoginModule} from './login/login.module';
 import {AuthGuard} from './shared/auth-guard';
 import {AuthenticationService} from './service/authentication.service';
@@ -67,7 +67,7 @@ export function initConfig(config: ColumnNamesService) {
     SwitchModule
   ],
   providers: [{ provide: APP_INITIALIZER, useFactory: initConfig, deps: [ColumnNamesService], multi: true },
-              { provide: DataSource, useClass: RestApiImpl },
+              { provide: DataSource, useClass: ElasticSearchLocalstorageImpl },
               AuthenticationService,
               AuthGuard,
               LoginGuard,

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts b/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
deleted file mode 100644
index 265f66b..0000000
--- a/metron-interface/metron-alerts/src/app/model/alerts-search-response.ts
+++ /dev/null
@@ -1,23 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Alert} from './alert';
-
-export class AlertsSearchResponse {
-  total = 0;
-  results: Alert[] = [];
-}

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/model/search-request.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/search-request.ts b/metron-interface/metron-alerts/src/app/model/search-request.ts
index 2150f2b..a37bd8d 100644
--- a/metron-interface/metron-alerts/src/app/model/search-request.ts
+++ b/metron-interface/metron-alerts/src/app/model/search-request.ts
@@ -1,4 +1,5 @@
 import {SortField} from './sort-field';
+import {INDEXES} from '../utils/constants';
 /**
  * Licensed to the Apache Software Foundation (ASF) under one
  * or more contributor license agreements.  See the NOTICE file
@@ -19,7 +20,7 @@ import {SortField} from './sort-field';
 export class SearchRequest {
   // _source: string[]; //TODO: This needs to be removed
   from: number;
-  indices: string[] = ['websphere', 'snort', 'asa', 'bro', 'yaf'];
+  indices: string[] = INDEXES;
   query: string;
   size: number;
   sort: SortField[];

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/model/search-response.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/model/search-response.ts b/metron-interface/metron-alerts/src/app/model/search-response.ts
new file mode 100644
index 0000000..c3fea27
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/model/search-response.ts
@@ -0,0 +1,23 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Alert} from './alert';
+
+export class SearchResponse {
+  total = 0;
+  results: Alert[] = [];
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/alert.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/alert.service.ts b/metron-interface/metron-alerts/src/app/service/alert.service.ts
deleted file mode 100644
index 7dabc4f..0000000
--- a/metron-interface/metron-alerts/src/app/service/alert.service.ts
+++ /dev/null
@@ -1,72 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Injectable, NgZone} from '@angular/core';
-import {Observable} from 'rxjs/Rx';
-import 'rxjs/add/observable/interval';
-import 'rxjs/add/operator/switchMap';
-import 'rxjs/add/operator/onErrorResumeNext';
-
-import {Alert} from '../model/alert';
-import {Http} from '@angular/http';
-import {DataSource} from './data-source';
-import {AlertsSearchResponse} from '../model/alerts-search-response';
-import {SearchRequest} from '../model/search-request';
-import {AlertSource} from '../model/alert-source';
-
-@Injectable()
-export class AlertService {
-
-  interval = 80000;
-  defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'};
-
-  constructor(private http: Http,
-              private dataSource: DataSource,
-              private ngZone: NgZone) { }
-
-  public search(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
-    return this.dataSource.getAlerts(searchRequest);
-  }
-
-  public pollSearch(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
-    return this.ngZone.runOutsideAngular(() => {
-      return this.ngZone.run(() => {
-        return Observable.interval(this.interval * 1000).switchMap(() => {
-          return this.dataSource.getAlerts(searchRequest);
-        });
-      });
-    });
-  }
-
-  public getAlert(sourceType: string, alertId: string): Observable<AlertSource> {
-    return this.dataSource.getAlert(sourceType, alertId);
-  }
-
-  public updateAlertState(alerts: Alert[], state: string, workflowId: string) {
-    let request = '';
-    for (let alert of alerts) {
-      request += '{ "update" : { "sensorType" : "' + alert.source['source:type'] + '", "guid" : "' + alert.source.guid + '" } }\n' +
-                  '{ "doc": { "alert_status": "' + state + '"';
-      if (workflowId) {
-        request += ', "workflow_id": "' + workflowId + '"';
-      }
-      request += ' }}\n';
-    }
-
-    return this.dataSource.updateAlertState(request);
-  }
-}

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts b/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
index 4077f30..ffd4ec1 100644
--- a/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
+++ b/metron-interface/metron-alerts/src/app/service/cluster-metadata.service.ts
@@ -18,11 +18,14 @@
 import {Injectable} from '@angular/core';
 import {Observable} from 'rxjs/Rx';
 import {Http} from '@angular/http';
+
+
 import {ColumnMetadata} from '../model/column-metadata';
 import {DataSource} from './data-source';
 
 @Injectable()
 export class ClusterMetaDataService {
+  defaultHeaders: {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'};
 
   constructor(private http: Http,
               private dataSource: DataSource) {
@@ -31,8 +34,4 @@ export class ClusterMetaDataService {
   getDefaultColumns(): Observable<ColumnMetadata[]> {
     return this.dataSource.getDefaultAlertTableColumnNames();
   }
-
-  getColumnMetaData(): Observable<ColumnMetadata[]> {
-    return this.dataSource.getAllFieldNames();
-  }
 }

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/data-source.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/data-source.ts b/metron-interface/metron-alerts/src/app/service/data-source.ts
index 28ee384..f4f90ed 100644
--- a/metron-interface/metron-alerts/src/app/service/data-source.ts
+++ b/metron-interface/metron-alerts/src/app/service/data-source.ts
@@ -22,7 +22,7 @@ import {ColumnMetadata} from '../model/column-metadata';
 import {ColumnNames} from '../model/column-names';
 import {TableMetadata} from '../model/table-metadata';
 import {SaveSearch} from '../model/save-search';
-import {AlertsSearchResponse} from '../model/alerts-search-response';
+import {SearchResponse} from '../model/search-response';
 import {SearchRequest} from '../model/search-request';
 import {AlertSource} from '../model/alert-source';
 
@@ -33,7 +33,7 @@ export abstract class DataSource {
   constructor(protected http: Http) {}
 
   // Calls to fetch alerts
-  abstract getAlerts(searchRequest: SearchRequest): Observable<AlertsSearchResponse>
+  abstract getAlerts(searchRequest: SearchRequest): Observable<SearchResponse>
   abstract getAlert(sourceType: string, alertId: string): Observable<AlertSource>
   abstract updateAlertState(request: any): Observable<{}>
 

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts
index f4e43d5..7982102 100644
--- a/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts
+++ b/metron-interface/metron-alerts/src/app/service/elasticsearch-localstorage-impl.ts
@@ -30,7 +30,7 @@ import {ColumnNames} from '../model/column-names';
 import {ColumnNamesService} from './column-names.service';
 import {TableMetadata} from '../model/table-metadata';
 import {SaveSearch} from '../model/save-search';
-import {AlertsSearchResponse} from '../model/alerts-search-response';
+import {SearchResponse} from '../model/search-response';
 import {SearchRequest} from '../model/search-request';
 import {AlertSource} from '../model/alert-source';
 
@@ -47,7 +47,7 @@ export class ElasticSearchLocalstorageImpl extends DataSource {
     new ColumnMetadata('alert_status', 'string')
   ];
 
-  getAlerts(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
+  getAlerts(searchRequest: SearchRequest): Observable<SearchResponse> {
     let url = '/search/*' + ElasticsearchUtils.excludeIndexName + '/_search';
     let request: any  = JSON.parse(JSON.stringify(searchRequest));
     request.query = { query_string: { query: searchRequest.query } };

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/rest-api-impl.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/rest-api-impl.ts b/metron-interface/metron-alerts/src/app/service/rest-api-impl.ts
deleted file mode 100644
index 061708d..0000000
--- a/metron-interface/metron-alerts/src/app/service/rest-api-impl.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-import {Observable} from 'rxjs/Rx';
-import {Headers, RequestOptions} from '@angular/http';
-
-import {HttpUtil} from '../utils/httpUtil';
-import {AlertsSearchResponse} from '../model/alerts-search-response';
-import {SearchRequest} from '../model/search-request';
-import {ElasticSearchLocalstorageImpl} from './elasticsearch-localstorage-impl';
-import {AlertSource} from '../model/alert-source';
-
-export class RestApiImpl extends ElasticSearchLocalstorageImpl {
-
-  getAlerts(searchRequest: SearchRequest): Observable<AlertsSearchResponse> {
-    let url = '/api/v1/search/search';
-    return this.http.post(url, searchRequest, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
-      .map(HttpUtil.extractData)
-      .catch(HttpUtil.handleError)
-      .onErrorResumeNext();
-  }
-
-  getAlert(sourceType: string, alertId: string): Observable<AlertSource> {
-    let url = '/api/v1/search/findOne';
-    let requestSchema = { guid: alertId, sensorType: sourceType};
-
-    return this.http.post(url, requestSchema, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
-    .map(HttpUtil.extractData)
-    .catch(HttpUtil.handleError)
-    .onErrorResumeNext();
-  }
-}

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/service/search.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/service/search.service.ts b/metron-interface/metron-alerts/src/app/service/search.service.ts
new file mode 100644
index 0000000..be3b1f6
--- /dev/null
+++ b/metron-interface/metron-alerts/src/app/service/search.service.ts
@@ -0,0 +1,112 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import {Injectable, NgZone} from '@angular/core';
+import {Headers, RequestOptions} from '@angular/http';
+import {Observable} from 'rxjs/Rx';
+import 'rxjs/add/observable/interval';
+import 'rxjs/add/operator/switchMap';
+import 'rxjs/add/operator/onErrorResumeNext';
+
+import {HttpUtil} from '../utils/httpUtil';
+import {Alert} from '../model/alert';
+import {Http} from '@angular/http';
+import {DataSource} from './data-source';
+import {SearchResponse} from '../model/search-response';
+import {SearchRequest} from '../model/search-request';
+import {AlertSource} from '../model/alert-source';
+import {INDEXES} from '../utils/constants';
+import {ColumnMetadata} from '../model/column-metadata';
+
+@Injectable()
+export class SearchService {
+
+  interval = 80000;
+  defaultHeaders = {'Content-Type': 'application/json', 'X-Requested-With': 'XMLHttpRequest'};
+
+  private static extractColumnNameDataFromRestApi(res: Response): ColumnMetadata[] {
+    let response: any = res || {};
+    let processedKeys: string[] = [];
+    let columnMetadatas: ColumnMetadata[] = [];
+
+    for (let index of Object.keys(response)) {
+      let indexMetaData = response[index];
+      for (let key of Object.keys(indexMetaData)) {
+        if (processedKeys.indexOf(key) === -1) {
+          processedKeys.push(key);
+          columnMetadatas.push(new ColumnMetadata(key, indexMetaData[key]));
+        }
+      }
+    }
+
+    return columnMetadatas;
+  }
+
+  constructor(private http: Http,
+              private dataSource: DataSource,
+              private ngZone: NgZone) { }
+
+  public getAlert(sourceType: string, alertId: string): Observable<AlertSource> {
+    let url = '/api/v1/search/findOne';
+    let requestSchema = { guid: alertId, sensorType: sourceType};
+
+    return this.http.post(url, requestSchema, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
+    .map(HttpUtil.extractData)
+    .catch(HttpUtil.handleError)
+    .onErrorResumeNext();
+  }
+
+  public getColumnMetaData(): Observable<ColumnMetadata[]> {
+    let url = '/api/v1/search/column/metadata';
+    return this.http.post(url, INDEXES, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
+    .map(HttpUtil.extractData)
+    .map(SearchService.extractColumnNameDataFromRestApi)
+    .catch(HttpUtil.handleError);
+  }
+
+  public pollSearch(searchRequest: SearchRequest): Observable<SearchResponse> {
+    return this.ngZone.runOutsideAngular(() => {
+      return this.ngZone.run(() => {
+        return Observable.interval(this.interval * 1000).switchMap(() => {
+          return this.search(searchRequest);
+        });
+      });
+    });
+  }
+
+  public search(searchRequest: SearchRequest): Observable<SearchResponse> {
+    let url = '/api/v1/search/search';
+    return this.http.post(url, searchRequest, new RequestOptions({headers: new Headers(this.defaultHeaders)}))
+    .map(HttpUtil.extractData)
+    .catch(HttpUtil.handleError)
+    .onErrorResumeNext();
+  }
+
+  public updateAlertState(alerts: Alert[], state: string, workflowId: string) {
+    let request = '';
+    for (let alert of alerts) {
+      request += '{ "update" : { "sensorType" : "' + alert.source['source:type'] + '", "guid" : "' + alert.source.guid + '" } }\n' +
+                  '{ "doc": { "alert_status": "' + state + '"';
+      if (workflowId) {
+        request += ', "workflow_id": "' + workflowId + '"';
+      }
+      request += ' }}\n';
+    }
+
+    return this.dataSource.updateAlertState(request);
+  }
+}

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/utils/constants.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/utils/constants.ts b/metron-interface/metron-alerts/src/app/utils/constants.ts
index da6d50c..a738a1d 100644
--- a/metron-interface/metron-alerts/src/app/utils/constants.ts
+++ b/metron-interface/metron-alerts/src/app/utils/constants.ts
@@ -20,3 +20,5 @@ export const ALERTS_RECENT_SEARCH = 'metron-alerts-recent-saved-search';
 export const ALERTS_SAVED_SEARCH = 'metron-alerts-saved-search';
 export const ALERTS_TABLE_METADATA = 'metron-alerts-table-metadata';
 export const ALERTS_COLUMN_NAMES = 'metron-alerts-column-names';
+
+export let INDEXES = ['websphere', 'snort', 'asa', 'bro', 'yaf'];

http://git-wip-us.apache.org/repos/asf/metron/blob/ea65a37c/metron-interface/metron-alerts/src/app/utils/elasticsearch-utils.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/utils/elasticsearch-utils.ts b/metron-interface/metron-alerts/src/app/utils/elasticsearch-utils.ts
index a86907b..0896f32 100644
--- a/metron-interface/metron-alerts/src/app/utils/elasticsearch-utils.ts
+++ b/metron-interface/metron-alerts/src/app/utils/elasticsearch-utils.ts
@@ -16,7 +16,7 @@
  * limitations under the License.
  */
 import {ColumnMetadata} from '../model/column-metadata';
-import {AlertsSearchResponse} from '../model/alerts-search-response';
+import {SearchResponse} from '../model/search-response';
 
 export class ElasticsearchUtils {
 
@@ -54,9 +54,9 @@ export class ElasticsearchUtils {
     return columnMetadata;
   }
 
-  public static extractAlertsData(res: Response): AlertsSearchResponse {
+  public static extractAlertsData(res: Response): SearchResponse {
     let response: any = res || {};
-    let alertsSearchResponse: AlertsSearchResponse = new AlertsSearchResponse();
+    let alertsSearchResponse: SearchResponse = new SearchResponse();
     alertsSearchResponse.total = response['hits']['total'];
     alertsSearchResponse.results = response['hits']['hits'];
     return alertsSearchResponse;