[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-05 Thread asfgit
Github user asfgit closed the pull request at:

https://github.com/apache/metron/pull/1190


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-04 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222823946
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

Looks good to me.  Latest commit includes this change.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-04 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222750671
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

> The question is what should happen when this unexpected condition does 
happen? Should it blow up and throw and exception or return a document if at 
least one DAO returns a valid one.

Ah, OK.  I'm groking it now.  We want it to return null; at least based on 
the javadocs defined in `RetrieveLatestDao.getLatest` and other places as null 
means nothing was found.  So functionally, we don't want it to throw that 
exception.  

But IMO it might benefit from some clarity.  I would suggest changing 
`getDocument` to `getLatestDocument` with some commentary and clarity on what 
it means if there is no Document or exception and what happens if there is an 
error in one of the underlying indices.

Feel free to tweak to your liking or disregard, but this is what I would do.
```
  /**
   * Returns the most recent {@link Document} from a list of {@link 
DocumentContainer}s.
   *
   * @param documentContainers A list of containers; each retrieved from a 
separate index.
   * @return The latest {@link Document} found.
   * @throws IOException If any of the {@link DocumentContainer}s contain 
an exception.
   */
  private Document getLatestDocument(List 
documentContainers) throws IOException {
Document latestDocument = null;
List error = new ArrayList<>();

for(DocumentContainer dc : documentContainers) {
  if(dc.getException().isPresent()) {
// collect each exception; multiple can occur, one in each index
Throwable e = dc.getException().get();
error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));

  } else if(dc.getDocument().isPresent()) {
Document d = dc.getDocument().get();
// is this the latest document so far?
if(latestDocument == null || latestDocument.getTimestamp() < 
d.getTimestamp()) {
  latestDocument = d;
}

  } else {
// no document was found in the index
latestDocument = null;
  }
}
if(error.size() > 0) {
  // report all of the errors encountered
  throw new IOException(Joiner.on("\n").join(error));
}
return latestDocument;
  }
```




---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-03 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222470180
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

No problem, don't mind working it out here and now.  The case that causes 
the test to fail (although I'm not sure that was the intention of the test) is 
where 2 DAOs are contained in a MultiIndexDao and the first DAO returns an 
invalid result (no document or exception) while the second returns a valid 
result.  I don't know what would cause a document to be missing both a document 
and an exception.  

The question is what should happen when this unexpected condition does 
happen?  Should it blow up and throw and exception or return a document if at 
least one DAO returns a valid one.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-03 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222421545
  
--- Diff: 
metron-platform/metron-elasticsearch/src/test/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDaoTest.java
 ---
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.elasticsearch.dao;
+
+import org.apache.metron.indexing.dao.AccessConfig;
+import org.apache.metron.indexing.dao.UpdateDaoTest;
+import org.apache.metron.indexing.dao.update.UpdateDao;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+
+public class ElasticsearchUpdateDaoTest extends UpdateDaoTest {
--- End diff --

I think you missed the javadoc here.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-03 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222420697
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

Hmm. Interesting.  I don't really understand what happens in that else 
condition then.  

The OCD side of me wants to make sure I understand this to ensure there is 
not a pre-existing bug.  But at the same time I can't fault you for this.  All 
you did was refactor this code out into a method.

It seems that a `DocumentContainer` should either have an exception 
(`dc.getException().isPresent()`) or it should have a document 
(`dc.getDocument.isPresent()`).  We would hit the else when neither of those 
are the case.  So under what conditions would a `DocumentContainer` have 
neither of those?  

I guess a `null` Document or null Throwable is added to the 
`DocumentContainer`?  I hope this is what we expect to happen.

```
if(dc.getException().isPresent()) { 
  ..
} else if(dc.getDocument.isPresent()) {
  ..
} else {
 // when does this occur? what do we expect to happen?
}
```


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-10-02 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r222000643
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

Upon further review, I'm not sure this is what we want.  This caused an 
integration test to fail because the result from the first DAO did not contain 
a document or exception while the result from the second DAO did contain a 
document.  Before this change, the document from the second DAO would have been 
returned.  I think we want to return a document if possible, even if all DAOs 
are not consistent.  Do you disagree?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217462174
  
--- Diff: 
metron-platform/metron-elasticsearch/src/test/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDaoTest.java
 ---
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.elasticsearch.dao;
+
+import org.apache.metron.indexing.dao.AccessConfig;
+import org.apache.metron.indexing.dao.UpdateDaoTest;
+import org.apache.metron.indexing.dao.update.UpdateDao;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+
+public class ElasticsearchUpdateDaoTest extends UpdateDaoTest {
--- End diff --

No problem


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217462087
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java
 ---
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+package org.apache.metron.indexing;
+
+import org.apache.metron.indexing.dao.IndexDao;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao;
+import org.apache.metron.indexing.dao.search.GetRequest;
+import org.apache.metron.indexing.dao.update.Document;
+
+import java.io.IOException;
+import java.util.List;
+
+public class InMemoryMetaAlertRetrieveLatestDao implements 
MetaAlertRetrieveLatestDao {
--- End diff --

Sure no problem.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217461869
  
--- Diff: 
metron-platform/metron-elasticsearch/src/test/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDaoTest.java
 ---
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.elasticsearch.dao;
+
+import org.apache.metron.indexing.dao.AccessConfig;
+import org.apache.metron.indexing.dao.UpdateDaoTest;
+import org.apache.metron.indexing.dao.update.UpdateDao;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+
+public class ElasticsearchUpdateDaoTest extends UpdateDaoTest {
--- End diff --

Ah, gotcha.  Could you add that to the javadoc?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217459943
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

I like it.  Will make that change.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217459852
  
--- Diff: 
metron-platform/metron-elasticsearch/src/test/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDaoTest.java
 ---
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.elasticsearch.dao;
+
+import org.apache.metron.indexing.dao.AccessConfig;
+import org.apache.metron.indexing.dao.UpdateDaoTest;
+import org.apache.metron.indexing.dao.update.UpdateDao;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+
+public class ElasticsearchUpdateDaoTest extends UpdateDaoTest {
--- End diff --

Check out UpdateDaoTest.  As I created tests for ElasticsearchUpdateDao, 
SolrUpdateDao, and HBaseDao I found myself copy/pasting the various tests.  So 
I consolidated them into a single test.  I believe there is value in having a 
single sets of tests for the UpdateDao interface methods that all the Daos must 
satisfy.  This class sets up it's Dao implementation to be used in the tests.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217441951
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java
 ---
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+package org.apache.metron.indexing;
+
+import org.apache.metron.indexing.dao.IndexDao;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao;
+import org.apache.metron.indexing.dao.search.GetRequest;
+import org.apache.metron.indexing.dao.update.Document;
+
+import java.io.IOException;
+import java.util.List;
+
+public class InMemoryMetaAlertRetrieveLatestDao implements 
MetaAlertRetrieveLatestDao {
--- End diff --

Would you mind adding this comment to the javadoc for this class?  I can 
imagine I will ask myself that question a few years down the road.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217441386
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -282,4 +276,27 @@ public Document getLatest(final String guid, String 
sensorType) throws IOExcepti
   public List getIndices() {
 return indices;
   }
+
+  private Document getDocument(List documentContainers) 
throws IOException {
+Document ret = null;
+List error = new ArrayList<>();
+for(DocumentContainer dc : documentContainers) {
+  if(dc.getException().isPresent()) {
+Throwable e = dc.getException().get();
+error.add(e.getMessage() + "\n" + ExceptionUtils.getStackTrace(e));
+  }
+  else {
+if(dc.getDocument().isPresent()) {
+  Document d = dc.getDocument().get();
+  if(ret == null || ret.getTimestamp() < d.getTimestamp()) {
+ret = d;
+  }
+}
+  }
+}
--- End diff --

Do we gain anything from a slight restructuring of your if/else chain that 
adds a sanity check? 

```
if(dc.getException().isPresent()) { 
  ..
} else if(dc.getDocument.isPresent()) {
  ..
} else {
  throw new IllegalStateException("Expected either document or exception; 
got neither");
}
```


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217439809
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -101,48 +103,59 @@ public void batchUpdate(Map> updates) throws IOExcept
   }
 
   @Override
-  public void addCommentToAlert(CommentAddRemoveRequest request) throws 
IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = getLatest(request.getGuid(), 
request.getSensorType());
-addCommentToAlert(request, latest);
+return addCommentToAlert(request, latest);
   }
 
-
+  /**
+   * Adds comments to an alert.  Updates are written to each Dao in 
parallel with the assumption that all updates
+   * are identical.  The first update to be applied is returned as the 
current version of the alert with comments added.
+   * @param request Request to add comments
+   * @param latest The latest version of the alert the comments will be 
added to.
+   * @return The complete alert document with comments added.
+   * @throws IOException
+   */
   @Override
-  public void addCommentToAlert(CommentAddRemoveRequest request, Document 
latest) throws IOException {
-List exceptions =
-indices.parallelStream().map(dao -> {
-  try {
-dao.addCommentToAlert(request, latest);
-return null;
-  } catch (Throwable e) {
-return dao.getClass() + ": " + e.getMessage() + "\n" + 
ExceptionUtils.getStackTrace(e);
-  }
-}).filter(Objects::nonNull).collect(Collectors.toList());
-if (exceptions.size() > 0) {
-  throw new IOException(Joiner.on("\n").join(exceptions));
-}
+  public Document addCommentToAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
+List output =
+indices.parallelStream().map(dao -> {
+  try {
+return new 
DocumentContainer(dao.addCommentToAlert(request, latest));
+  } catch (Throwable e) {
+return new DocumentContainer(e);
+  }
+}).collect(Collectors.toList());
--- End diff --

Nice!  I like your approach.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-13 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r217438881
  
--- Diff: 
metron-platform/metron-elasticsearch/src/test/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDaoTest.java
 ---
@@ -0,0 +1,48 @@
+/*
+ * 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.
+ */
+
+package org.apache.metron.elasticsearch.dao;
+
+import org.apache.metron.indexing.dao.AccessConfig;
+import org.apache.metron.indexing.dao.UpdateDaoTest;
+import org.apache.metron.indexing.dao.update.UpdateDao;
+import org.elasticsearch.client.transport.TransportClient;
+import org.junit.Before;
+
+import static org.mockito.Mockito.mock;
+
+public class ElasticsearchUpdateDaoTest extends UpdateDaoTest {
--- End diff --

What is this test for?  There seems to be no actual tests.  Maybe you 
forgot to push a commit?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216739437
  
--- Diff: 
metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrUpdateDao.java
 ---
@@ -117,18 +118,19 @@ public void batchUpdate(Map> updates) throws IOExcept
 } catch (SolrServerException e) {
   throw new IOException(e);
 }
+return updates;
   }
 
   @Override
-  public void addCommentToAlert(CommentAddRemoveRequest request) throws 
IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = retrieveLatestDao.getLatest(request.getGuid(), 
request.getSensorType());
-addCommentToAlert(request, latest);
+return addCommentToAlert(request, latest);
   }
 
   @Override
-  public void addCommentToAlert(CommentAddRemoveRequest request, Document 
latest) throws IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
 if (latest == null) {
-  return;
+  return null;
--- End diff --

Should we also treat this as an exceptional condition too?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216733487
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -121,20 +131,30 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 if (exceptions.size() > 0) {
   throw new IOException(Joiner.on("\n").join(exceptions));
 }
+return newVersions.get(0);
   }
 
   @Override
-  public void removeCommentFromAlert(CommentAddRemoveRequest request) 
throws IOException {
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = getLatest(request.getGuid(), 
request.getSensorType());
-removeCommentFromAlert(request, latest);
+return removeCommentFromAlert(request, latest);
   }
 
+  /**
+   * Removes comments from an alert.  Updates are written to each Dao in 
parallel with the assumption that all updates
+   * are identical.  The first update to be applied is returned as the 
current version of the alert with comments removed.
+   * @param request Request to remove comments
+   * @param latest The latest version of the alert the comments will be 
removed from.
+   * @return The complete alert document with comments removed.
+   * @throws IOException
+   */
   @Override
-  public void removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
+final List newVersions = new ArrayList<>();
--- End diff --

Same here... If we do it this way, we just need to make this a thread-safe 
list.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216725905
  
--- Diff: 
metron-platform/metron-elasticsearch/src/main/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDao.java
 ---
@@ -108,20 +109,21 @@ public void batchUpdate(Map> updates) throws IOExcept
   throw new IOException(
   "ElasticsearchDao upsert failed: " + 
bulkResponse.buildFailureMessage());
 }
+return updates;
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void addCommentToAlert(CommentAddRemoveRequest request) throws 
IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = retrieveLatestDao.getLatest(request.getGuid(), 
request.getSensorType());
-addCommentToAlert(request, latest);
+return addCommentToAlert(request, latest);
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void addCommentToAlert(CommentAddRemoveRequest request, Document 
latest) throws IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
 if (latest == null) {
-  return;
+  return null;
--- End diff --

The `latest` would only be null if there was a request to comment on a 
non-existent meta-alert, correct? If that is the case, then this *should* never 
happen.  Wouldn't it be better to throw an exception with an appropriate error 
message so we can investigate the thing that should not have happened?




---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216727723
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/HBaseDao.java
 ---
@@ -280,14 +282,14 @@ protected Put buildPut(Document update) throws 
IOException {
 
   @Override
   @SuppressWarnings("unchecked")
-  public void addCommentToAlert(CommentAddRemoveRequest request) throws 
IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = getLatest(request.getGuid(), 
request.getSensorType());
-addCommentToAlert(request, latest);
+return addCommentToAlert(request, latest);
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void addCommentToAlert(CommentAddRemoveRequest request, Document 
latest) throws IOException {
+  public Document addCommentToAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
 if (latest == null || latest.getDocument() == null) {
   throw new IOException("Unable to add comment to document that 
doesn't exist");
 }
--- End diff --

This seems to match what I am suggesting we do in the Elasticsearch 
implementation.  If we don't have a document, we should thrown an exception.

I'd also argue that the error message provides no useful information to 
help debug the problem.  But that is a pre-existing condition.  Would be nice 
to clean-up though.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216735553
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java
 ---
@@ -170,21 +169,51 @@ protected Document 
buildCreateDocument(Iterable alerts, List g
 return updates;
   }
 
+  /**
+   * Adds alerts to a metaalert, based on a list of GetRequests provided 
for retrieval.
+   * @param metaAlertGuid The GUID of the metaalert to be given new 
children.
+   * @param alertRequests GetRequests for the appropriate alerts to add.
+   * @return The updated metaalert with alerts added.
+   */
+  @Override
+  public Document addAlertsToMetaAlert(String metaAlertGuid, 
List alertRequests)
+  throws IOException {
+
+Document metaAlert = retrieveLatestDao
+.getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE);
+if (MetaAlertStatus.ACTIVE.getStatusString()
+
.equals(metaAlert.getDocument().get(MetaAlertConstants.STATUS_FIELD))) {
+  Iterable alerts = 
retrieveLatestDao.getAllLatest(alertRequests);
+  Map> updates = 
buildAddAlertToMetaAlertUpdates(metaAlert, alerts);
+  update(updates);
+  return metaAlert;
+} else {
+  throw new IllegalStateException("Adding alerts to an INACTIVE meta 
alert is not allowed");
+}
+  }
+
+  /**
+   * Removes alerts from a metaalert, based on a list of GetRequests 
provided for retrieval.
+   * @param metaAlertGuid The GUID of the metaalert to remove children 
from.
+   * @param alertRequests A list of GetReqests that will provide the 
alerts to remove
+   * @return The updated metaalert with alerts removed.
+   * @throws IllegalStateException If the metaalert is inactive.
+   */
   @Override
   @SuppressWarnings("unchecked")
-  public boolean removeAlertsFromMetaAlert(String metaAlertGuid, 
List alertRequests)
-  throws IOException {
+  public Document removeAlertsFromMetaAlert(String metaAlertGuid, 
List alertRequests)
+  throws IOException, IllegalStateException {
 Document metaAlert = retrieveLatestDao
 .getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE);
 if (metaAlert == null) {
-  return false;
+  return null;
--- End diff --

Should we also treat this as an exceptional condition?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216728030
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/HBaseDao.java
 ---
@@ -309,28 +311,28 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 
 Document newVersion = new Document(latest);
 newVersion.getDocument().put(COMMENTS_FIELD, commentsMap);
-update(newVersion, Optional.empty());
+return update(newVersion, Optional.empty());
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void removeCommentFromAlert(CommentAddRemoveRequest request)
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request)
   throws IOException {
 Document latest = getLatest(request.getGuid(), 
request.getSensorType());
-removeCommentFromAlert(request, latest);
+return removeCommentFromAlert(request, latest);
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest)
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest)
   throws IOException {
 if (latest == null || latest.getDocument() == null) {
   throw new IOException("Unable to remove comment document that 
doesn't exist");
 }
 List> commentMap = (List>) 
latest.getDocument().get(COMMENTS_FIELD);
 // Can't remove anything if there's nothing there
 if (commentMap == null) {
-  return;
+  return null;
--- End diff --

Should we also treat this as an exceptional condition?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216733316
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -121,20 +131,30 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 if (exceptions.size() > 0) {
   throw new IOException(Joiner.on("\n").join(exceptions));
 }
+return newVersions.get(0);
--- End diff --

I don't think we can safely add the Documents to `newVersions` since it is 
not a thread-safe list.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216726476
  
--- Diff: 
metron-platform/metron-elasticsearch/src/main/java/org/apache/metron/elasticsearch/dao/ElasticsearchUpdateDao.java
 ---
@@ -133,21 +135,21 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 
 Document newVersion = new Document(latest);
 newVersion.getDocument().put(COMMENTS_FIELD, originalComments);
-update(newVersion, Optional.empty());
+return update(newVersion, Optional.empty());
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void removeCommentFromAlert(CommentAddRemoveRequest request) 
throws IOException {
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request) 
throws IOException {
 Document latest = retrieveLatestDao.getLatest(request.getGuid(), 
request.getSensorType());
-removeCommentFromAlert(request, latest);
+return removeCommentFromAlert(request, latest);
   }
 
   @Override
   @SuppressWarnings("unchecked")
-  public void removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest) throws IOException {
 if (latest == null) {
-  return;
+  return null;
--- End diff --

Same comment here.  We should never see a request to remove a comment from 
a doc that doesn't exist.  So let's throw an exception with a message that we 
can use to debug the problem.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216739553
  
--- Diff: 
metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrUpdateDao.java
 ---
@@ -172,7 +174,7 @@ public void 
removeCommentFromAlert(CommentAddRemoveRequest request, Document lat
 // Can't remove anything if there's nothing there
 if (commentMap == null) {
   LOG.debug("Provided alert had no comments to be able to remove 
from");
-  return;
+  return null;
--- End diff --

Should we also treat this as an exceptional condition too?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216739478
  
--- Diff: 
metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrUpdateDao.java
 ---
@@ -149,21 +151,21 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 
 Document newVersion = new Document(latest);
 newVersion.getDocument().put(COMMENTS_FIELD, commentStrs);
-update(newVersion, Optional.empty());
+return update(newVersion, Optional.empty());
   }
 
   @Override
-  public void removeCommentFromAlert(CommentAddRemoveRequest request)
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request)
   throws IOException {
 Document latest = retrieveLatestDao.getLatest(request.getGuid(), 
request.getSensorType());
-removeCommentFromAlert(request, latest);
+return removeCommentFromAlert(request, latest);
   }
 
   @Override
-  public void removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest)
+  public Document removeCommentFromAlert(CommentAddRemoveRequest request, 
Document latest)
   throws IOException {
 if (latest == null) {
-  return;
+  return null;
--- End diff --

Should we also treat this as an exceptional condition too?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-11 Thread nickwallen
Github user nickwallen commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216735006
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java
 ---
@@ -170,21 +169,51 @@ protected Document 
buildCreateDocument(Iterable alerts, List g
 return updates;
   }
 
+  /**
+   * Adds alerts to a metaalert, based on a list of GetRequests provided 
for retrieval.
+   * @param metaAlertGuid The GUID of the metaalert to be given new 
children.
+   * @param alertRequests GetRequests for the appropriate alerts to add.
+   * @return The updated metaalert with alerts added.
+   */
+  @Override
+  public Document addAlertsToMetaAlert(String metaAlertGuid, 
List alertRequests)
+  throws IOException {
+
+Document metaAlert = retrieveLatestDao
--- End diff --

Don't we need a null check here?  What happens if there is no metaAlert?


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216092662
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java
 ---
@@ -61,8 +60,8 @@
   0x54,0x79,0x70,0x65
   };
 
-  @BeforeClass
-  public static void startHBase() throws Exception {
+  @Before
--- End diff --

Tables need to be cleared after each test.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216092562
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java
 ---
@@ -985,6 +1024,30 @@ protected boolean findCreatedDocs(List 
getRequests)
 throw new OriginalNotFoundException("Count not find guids after " + 
MAX_RETRIES + "tries");
   }
 
+  @SuppressWarnings("unchecked")
+  protected void assertEquals(Map expected, Map actual) {
--- End diff --

This method is needed to handle type mismatches (Integer to Long and Float 
to Double) and child alert ordering.
 These fields are not defined in the metaalert template so ES is guessing 
the type.  When read back some field types are different vs when they were 
written.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216091611
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertUpdateDao.java
 ---
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+package org.apache.metron.indexing.dao;
+
+import org.apache.metron.indexing.dao.metaalert.MetaAlertConfig;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertConstants;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertCreateRequest;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao;
+import 
org.apache.metron.indexing.dao.metaalert.lucene.AbstractLuceneMetaAlertUpdateDao;
+import org.apache.metron.indexing.dao.search.GetRequest;
+import org.apache.metron.indexing.dao.search.InvalidCreateException;
+import org.apache.metron.indexing.dao.update.CommentAddRemoveRequest;
+import org.apache.metron.indexing.dao.update.Document;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Optional;
+
+public class InMemoryMetaAlertUpdateDao extends 
AbstractLuceneMetaAlertUpdateDao {
--- End diff --

Extending the AbstractLuceneMetaAlertUpdateDao class lets us reuse code 
from that implementation.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216091258
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java
 ---
@@ -174,145 +193,29 @@ public SearchResponse 
getAllMetaAlertsForAlert(String guid) throws InvalidSearch
 
   @SuppressWarnings("unchecked")
   @Override
-  public MetaAlertCreateResponse createMetaAlert(MetaAlertCreateRequest 
request)
-  throws InvalidCreateException {
-List alertRequests = request.getAlerts();
-if (alertRequests.isEmpty()) {
-  MetaAlertCreateResponse response = new MetaAlertCreateResponse();
-  response.setCreated(false);
-  return response;
-}
-// Build meta alert json.  Give it a reasonable GUID
-JSONObject metaAlert = new JSONObject();
-String metaAlertGuid =
-"meta_" + 
(InMemoryDao.BACKING_STORE.get(getMetaAlertIndex()).size() + 1);
-metaAlert.put(GUID, metaAlertGuid);
-
-JSONArray groupsArray = new JSONArray();
-groupsArray.addAll(request.getGroups());
-metaAlert.put(MetaAlertConstants.GROUPS_FIELD, groupsArray);
-
-// Retrieve the alert for each guid
-// For the purpose of testing, we're just using guids for the alerts 
field and grabbing the scores.
-JSONArray alertArray = new JSONArray();
-List threatScores = new ArrayList<>();
-Collection alertGuids = new ArrayList<>();
-for (GetRequest alertRequest : alertRequests) {
-  SearchRequest searchRequest = new SearchRequest();
-  
searchRequest.setIndices(ImmutableList.of(alertRequest.getIndex().get()));
-  searchRequest.setQuery("guid:" + alertRequest.getGuid());
-  try {
-SearchResponse searchResponse = search(searchRequest);
-List searchResults = searchResponse.getResults();
-if (searchResults.size() > 1) {
-  throw new InvalidCreateException(
-  "Found more than one result for: " + alertRequest.getGuid() 
+ ". Values: "
-  + searchResults
-  );
-}
-
-if (searchResults.size() == 1) {
-  SearchResult result = searchResults.get(0);
-  alertArray.add(result.getSource());
-  Double threatScore = Double
-  .parseDouble(
-  
result.getSource().getOrDefault(MetaAlertConstants.THREAT_FIELD_DEFAULT, "0")
-  .toString());
-
-  threatScores.add(threatScore);
-}
-  } catch (InvalidSearchException e) {
-throw new InvalidCreateException("Unable to find guid: " + 
alertRequest.getGuid(), e);
-  }
-  alertGuids.add(alertRequest.getGuid());
-}
-
-metaAlert.put(MetaAlertConstants.ALERT_FIELD, alertArray);
-metaAlert.putAll(new MetaScores(threatScores).getMetaScores());
-metaAlert.put(MetaAlertConstants.STATUS_FIELD, 
MetaAlertStatus.ACTIVE.getStatusString());
-
-// Add the alert to the store, but make sure not to overwrite existing 
results
-
InMemoryDao.BACKING_STORE.get(getMetaAlertIndex()).add(metaAlert.toJSONString());
-
-METAALERT_STORE.put(metaAlertGuid, new HashSet<>(alertGuids));
-
-MetaAlertCreateResponse createResponse = new MetaAlertCreateResponse();
-createResponse.setGuid(metaAlertGuid);
-createResponse.setCreated(true);
-return createResponse;
+  public Document createMetaAlert(MetaAlertCreateRequest request)
+  throws InvalidCreateException, IOException {
+return metaAlertUpdateDao.createMetaAlert(request);
--- End diff --

Now we're delegating to the AbstractLuceneMetaAlertUpdateDao class instead 
of duplicating it.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216090892
  
--- Diff: 
metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java
 ---
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+package org.apache.metron.indexing;
+
+import org.apache.metron.indexing.dao.IndexDao;
+import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao;
+import org.apache.metron.indexing.dao.search.GetRequest;
+import org.apache.metron.indexing.dao.update.Document;
+
+import java.io.IOException;
+import java.util.List;
+
+public class InMemoryMetaAlertRetrieveLatestDao implements 
MetaAlertRetrieveLatestDao {
--- End diff --

This class doesn't do much but is needed to compose an 
InMemoryMetaAlertUpdateDao.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216090740
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java
 ---
@@ -170,21 +169,51 @@ protected Document 
buildCreateDocument(Iterable alerts, List g
 return updates;
   }
 
+  /**
+   * Adds alerts to a metaalert, based on a list of GetRequests provided 
for retrieval.
+   * @param metaAlertGuid The GUID of the metaalert to be given new 
children.
+   * @param alertRequests GetRequests for the appropriate alerts to add.
+   * @return The updated metaalert with alerts added.
+   */
+  @Override
+  public Document addAlertsToMetaAlert(String metaAlertGuid, 
List alertRequests)
--- End diff --

This was moved from the Elasticsearch Dao implementation essentially making 
it the default method for adding alerts to metaalerts (the logic in the Solr 
implementation is different).  This allows us to reuse this code in the 
InMemory implementation.


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
Github user merrimanr commented on a diff in the pull request:

https://github.com/apache/metron/pull/1190#discussion_r216090450
  
--- Diff: 
metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/MultiIndexDao.java
 ---
@@ -121,20 +131,30 @@ public void addCommentToAlert(CommentAddRemoveRequest 
request, Document latest)
 if (exceptions.size() > 0) {
   throw new IOException(Joiner.on("\n").join(exceptions));
 }
+return newVersions.get(0);
--- End diff --

Here we are collecting each updated document in a list.  In theory they are 
all the same so it shouldn't matter which one we return.  Is there a better way 
to do this?  


---


[GitHub] metron pull request #1190: METRON-1771: Update REST endpoints to support eve...

2018-09-07 Thread merrimanr
GitHub user merrimanr opened a pull request:

https://github.com/apache/metron/pull/1190

METRON-1771: Update REST endpoints to support eventually consistent UI 
updates

## Contributor Comments
This PR updates several REST endpoints to return the state of an object on 
update operations.  These endpoints include:

- MetaAlertController
  - create
  - addAlertsToMetaAlert 
  - removeAlertsFromMetaAlert 
  - updateMetaAlertStatus 

- UpdateController
  - patch
  - replace
  - addCommentToAlert
  - removeCommentFromAlert

 The general approach is to change the return type of the various Dao 
methods that update objects to return the updated document.  In most cases this 
was straightforward but did require small changes in several files due to how 
the Dao classes are composed and the various implementations that exist (ES, 
Solr, InMemory, etc).  

Perhaps the most significant change was to the InMemoryMetaAlertDao classes 
used for REST integration testing because they were no longer sufficient after 
the interface change.  Before they stored a mapping between metaalerts and 
child alerts which worked fine when just returning a true/false on 
adding/removing child alerts.  With this PR the InMemoryMetaAlertDao classes 
now must return the full object.   As I worked through updating these methods 
to do this, I found myself rewriting the methods in 
AbstractLuceneMetaAlertUpdateDao.  Instead of doing that, I refactored the 
InMemoryMetaAlertDao classes to more closely match how the MetaAlertDao classes 
are composed and was able to reuse the implementations in 
AbstractLuceneMetaAlertUpdateDao.  I feel this makes the InMemoryMetaAlertDao 
classes smaller and easier to maintain moving forward.

### Changes Included

- Updated the various *UpdateDao interfaces and implementations to return 
Documents
- Updated the REST services and controllers to match the new interfaces
- Changed the InMemoryDao classes as described above
- Updated the various unit and integration tests to verify that correct 
documents are returned (includes new tests in several cases)
- Updated and added documentation as needed
- Fixed a bug in HBaseDaoIntegrationTest.java where tables were not being 
cleared after each test

### Testing
In addition to unit and integration tests passing, I have tested this in 
full dev with Elasticsearch.  The testing approach is the same for each 
endpoint listed above:  send a request and verify the document that is returned 
includes the expected change.  Here are a couple of examples

 Testing the patch endpoint

Send a patch request:
```
curl -X PATCH --header 'Content-Type: application/json' --header 'Accept: 
application/json' -d '{
  "guid": "1881af3c-88df-4e72-8e81-34538b6e774b",
  "patch": [
{
  "op":"add",
  "path":"/newField",
  "value":"newValue"
}
  ],
  "sensorType": "bro"
}' 'http://node1:8082/api/v1/update/patch'
```
The response should contain the full document along with the update, in 
this case a `newField` field added with a value of `newValue`:
```
{
  "timestamp": 1536185190979,
  "document": {
"bro_timestamp": "1536182284.908185",
"ip_dst_port": 8080,
...
"newField": "newValue"
  },
  "guid": "1881af3c-88df-4e72-8e81-34538b6e774b",
  "sensorType": "bro"
}
```

 Testing the metaalert create endpoint:

Create a metaalert:
```
curl -X POST --header 'Content-Type: application/json' --header 'Accept: 
application/json' -d '{
  "alerts": [
{
  "guid": "0588e788-3a91-4113-94a0-d80daec00d05",
  "sensorType": "snort"
}
  ],
  "groups": [
"group1"
  ]
}' 'http://node1:8082/api/v1/metaalert/create'
```
This should return the full metaalert along with the child alert:
```
{
  "timestamp": 1536203159546,
  "document": {
"average": 10,
"max": 10,
"metron_alert": [
  {
"msg": "'snort test alert'",
...
"metaalerts": [
  "f65e4d0e-bdad-4ac7-ab22-4cf207c3fb2e"
]
  }
],
"threat:triage:score": 10,
"count": 1,
"groups": [
  "group1"
],
"sum": 10,
"source:type": "metaalert",
"min": 10,
"median": 10,
"guid": "f65e4d0e-bdad-4ac7-ab22-4cf207c3fb2e",
"timestamp": 1536203159546,
"status": "active"
  },
  "guid": "f65e4d0e-bdad-4ac7-ab22-4cf207c3fb2e",
  "sensorType": "metaalert"
}
```
I also tested every endpoint using the Alerts UI.  Everything should 
continue working as expected.

### Outstanding items
There are a couple of changes I'm not quite sure about and would like