http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java b/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java index 4d48075..096baf1 100644 --- a/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java +++ b/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDao.java @@ -24,16 +24,17 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.function.Supplier; import java.util.stream.Collectors; +import java.util.stream.StreamSupport; + import org.apache.metron.common.Constants; -import org.apache.metron.common.configuration.ConfigurationsUtils; import org.apache.metron.indexing.dao.RetrieveLatestDao; import org.apache.metron.indexing.dao.metaalert.MetaAlertConfig; import org.apache.metron.indexing.dao.metaalert.MetaAlertConstants; @@ -80,15 +81,16 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat * @param retrieveLatestDao DAO to retrieve the item to be patched * @param request The patch request. * @param timestamp Optionally a timestamp to set. If not specified then current time is used. + * @return The patched document * @throws OriginalNotFoundException If no original document is found to patch. * @throws IOException If an error occurs performing the patch. */ @Override - public void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, + public Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, Optional<Long> timestamp) throws OriginalNotFoundException, IOException { if (isPatchAllowed(request)) { - updateDao.patch(retrieveLatestDao, request, timestamp); + return updateDao.patch(retrieveLatestDao, request, timestamp); } else { throw new IllegalArgumentException( "Meta alert patches are not allowed for /alert or /status paths. " @@ -97,7 +99,7 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat } @Override - public void batchUpdate(Map<Document, Optional<String>> updates) { + public Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) { throw new UnsupportedOperationException("Meta alerts do not allow for bulk updates"); } @@ -170,21 +172,65 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat 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<GetRequest> alertRequests) + throws IOException { + Document metaAlert = retrieveLatestDao + .getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE); + if (metaAlert == null) { + throw new IOException(String.format("Unable to add alerts to meta alert. Meta alert with guid %s cannot be found.", + metaAlertGuid)); + } + if (MetaAlertStatus.ACTIVE.getStatusString() + .equals(metaAlert.getDocument().get(MetaAlertConstants.STATUS_FIELD))) { + Iterable<Document> alerts = retrieveLatestDao.getAllLatest(alertRequests); + Set<String> missingAlerts = getMissingAlerts(alertRequests, alerts); + if (!missingAlerts.isEmpty()) { + throw new IOException(String.format("Unable to add alerts to meta alert. Alert with guid %s cannot be found.", + missingAlerts.iterator().next())); + } + Map<Document, Optional<String>> 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<GetRequest> alertRequests) - throws IOException { + public Document removeAlertsFromMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) + throws IOException, IllegalStateException { Document metaAlert = retrieveLatestDao .getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE); if (metaAlert == null) { - return false; + throw new IOException(String.format("Unable to remove alerts from meta alert. Meta alert with guid %s cannot be found.", + metaAlertGuid)); } if (MetaAlertStatus.ACTIVE.getStatusString() .equals(metaAlert.getDocument().get(MetaAlertConstants.STATUS_FIELD))) { Iterable<Document> alerts = retrieveLatestDao.getAllLatest(alertRequests); + Set<String> missingAlerts = getMissingAlerts(alertRequests, alerts); + if (!missingAlerts.isEmpty()) { + throw new IOException(String.format("Unable to remove alerts from meta alert. Alert with guid %s cannot be found.", + missingAlerts.iterator().next())); + } Map<Document, Optional<String>> updates = buildRemoveAlertsFromMetaAlert(metaAlert, alerts); update(updates); - return updates.size() != 0; + return metaAlert; } else { throw new IllegalStateException("Removing alerts from an INACTIVE meta alert is not allowed"); } @@ -213,10 +259,14 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat } @Override - public boolean updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) + public Document updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) throws IOException { Document metaAlert = retrieveLatestDao .getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE); + if (metaAlert == null) { + throw new IOException(String.format("Unable to update meta alert status. Meta alert with guid %s cannot be found.", + metaAlertGuid)); + } String currentStatus = (String) metaAlert.getDocument().get(MetaAlertConstants.STATUS_FIELD); boolean metaAlertUpdated = !status.getStatusString().equals(currentStatus); if (metaAlertUpdated) { @@ -231,7 +281,7 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat Map<Document, Optional<String>> updates = buildStatusChangeUpdates(metaAlert, alerts, status); update(updates); } - return metaAlertUpdated; + return metaAlert; } /** @@ -334,4 +384,13 @@ public abstract class AbstractLuceneMetaAlertUpdateDao implements MetaAlertUpdat } // else we have no updates, so don't do anything } + protected Set<String> getMissingAlerts(List<GetRequest> alertRequests, Iterable<Document> results) throws IOException { + Set<String> requestGuids = alertRequests.stream().map(GetRequest::getGuid).collect(Collectors.toSet()); + Set<String> resultGuids = StreamSupport.stream(results.spliterator(), false) + .map(Document::getGuid).collect(Collectors.toSet()); + Set<String> missingGuids = new HashSet<>(requestGuids); + missingGuids.removeAll(resultGuids); + return missingGuids; + } + }
http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/update/UpdateDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/update/UpdateDao.java b/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/update/UpdateDao.java index b5f38e4..8f6f6b0 100644 --- a/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/update/UpdateDao.java +++ b/metron-platform/metron-indexing/src/main/java/org/apache/metron/indexing/dao/update/UpdateDao.java @@ -18,7 +18,6 @@ package org.apache.metron.indexing.dao.update; import java.io.IOException; -import java.util.HashMap; import java.util.Map; import java.util.Optional; import org.apache.metron.common.utils.JSONUtils; @@ -33,25 +32,27 @@ public interface UpdateDao { * * @param update The document to replace from the index. * @param index The index where the document lives. + * @return The updated document * @throws IOException If an error occurs during the update. */ - void update(Document update, Optional<String> index) throws IOException; + Document update(Document update, Optional<String> index) throws IOException; /** * Similar to the update method but accepts multiple documents and performs updates in batch. * * @param updates A map of the documents to update to the index where they live. + * @return The updated documents. * @throws IOException If an error occurs during the updates. */ - void batchUpdate(Map<Document, Optional<String>> updates) throws IOException; + Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) throws IOException; - void addCommentToAlert(CommentAddRemoveRequest request) throws IOException; + Document addCommentToAlert(CommentAddRemoveRequest request) throws IOException; - void removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException; + Document removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException; - void addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException; + Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException; - void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException; + Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException; /** @@ -59,14 +60,15 @@ public interface UpdateDao { * https://tools.ietf.org/html/rfc6902) * @param request The patch request * @param timestamp Optionally a timestamp to set. If not specified then current time is used. + * @return The patched document. * @throws OriginalNotFoundException If the original is not found, then it cannot be patched. * @throws IOException If an error occurs while patching. */ - default void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request + default Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request , Optional<Long> timestamp ) throws OriginalNotFoundException, IOException { Document d = getPatchedDocument(retrieveLatestDao, request, timestamp); - update(d, Optional.ofNullable(request.getIndex())); + return update(d, Optional.ofNullable(request.getIndex())); } default Document getPatchedDocument(RetrieveLatestDao retrieveLatestDao, PatchRequest request, @@ -94,15 +96,16 @@ public interface UpdateDao { * Replace a document in an index. * @param request The replacement request. * @param timestamp The timestamp (optional) of the update. If not specified, then current time will be used. + * @return The replaced document. * @throws IOException If an error occurs during replacement. */ - default void replace(ReplaceRequest request, Optional<Long> timestamp) + default Document replace(ReplaceRequest request, Optional<Long> timestamp) throws IOException { Document d = new Document(request.getReplacement(), request.getGuid(), request.getSensorType(), timestamp.orElse(System.currentTimeMillis()) ); - update(d, Optional.ofNullable(request.getIndex())); + return update(d, Optional.ofNullable(request.getIndex())); } } http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java new file mode 100644 index 0000000..28891d9 --- /dev/null +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/InMemoryMetaAlertRetrieveLatestDao.java @@ -0,0 +1,49 @@ +/* + * 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; + +/** + * This class is needed to compose an InMemoryMetaAlertUpdateDao implementation. This allows the + * InMemoryMetaAlertUpdateDao class to extend AbstractLuceneMetaAlertUpdateDao and reuse common logic in that class. + */ +public class InMemoryMetaAlertRetrieveLatestDao implements MetaAlertRetrieveLatestDao { + + private IndexDao indexDao; + + public InMemoryMetaAlertRetrieveLatestDao(IndexDao indexDao) { + this.indexDao = indexDao; + } + + @Override + public Document getLatest(String guid, String sensorType) throws IOException { + return indexDao.getLatest(guid, sensorType); + } + + @Override + public Iterable<Document> getAllLatest(List<GetRequest> getRequests) throws IOException { + return indexDao.getAllLatest(getRequests); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/HBaseDaoTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/HBaseDaoTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/HBaseDaoTest.java new file mode 100644 index 0000000..d4823db --- /dev/null +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/HBaseDaoTest.java @@ -0,0 +1,41 @@ +/* + * 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.update.UpdateDao; +import org.junit.Before; + +/** + * This class returns the HBaseDao implementation to be used in UpdateDaoTest. UpdateDaoTest contains a + * common set of tests that all Dao implementations must pass. + */ +public class HBaseDaoTest extends UpdateDaoTest{ + + private HBaseDao dao; + + @Before + public void setup() { + dao = new HBaseDao(); + } + + @Override + public UpdateDao getUpdateDao() { + return dao; + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryDao.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryDao.java index e306567..f49a6ad 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryDao.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryDao.java @@ -248,7 +248,7 @@ public class InMemoryDao implements IndexDao { } @Override - public void update(Document update, Optional<String> index) throws IOException { + public Document update(Document update, Optional<String> index) throws IOException { for (Map.Entry<String, List<String>> kv : BACKING_STORE.entrySet()) { if (kv.getKey().startsWith(update.getSensorType())) { for (Iterator<String> it = kv.getValue().iterator(); it.hasNext(); ) { @@ -261,13 +261,15 @@ public class InMemoryDao implements IndexDao { kv.getValue().add(JSONUtils.INSTANCE.toJSON(update.getDocument(), true)); } } + return update; } @Override - public void batchUpdate(Map<Document, Optional<String>> updates) throws IOException { + public Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) throws IOException { for (Map.Entry<Document, Optional<String>> update : updates.entrySet()) { update(update.getKey(), update.getValue()); } + return updates; } @Override @@ -293,19 +295,23 @@ public class InMemoryDao implements IndexDao { } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) { + public Document addCommentToAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + return null; } public static void setColumnMetadata(Map<String, Map<String, FieldType>> columnMetadata) { http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java index cb8837b..dbd3cb6 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertDao.java @@ -18,26 +18,24 @@ package org.apache.metron.indexing.dao; -import static org.apache.metron.common.Constants.GUID; +import static org.apache.metron.common.Constants.SENSOR_TYPE; -import com.google.common.collect.ImmutableList; import java.io.IOException; -import java.util.ArrayList; -import java.util.Collection; import java.util.HashMap; -import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.stream.Collectors; +import java.util.function.Supplier; import org.adrianwalker.multilinestring.Multiline; import org.apache.metron.common.utils.JSONUtils; +import org.apache.metron.indexing.InMemoryMetaAlertRetrieveLatestDao; +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.MetaAlertCreateResponse; import org.apache.metron.indexing.dao.metaalert.MetaAlertDao; +import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao; import org.apache.metron.indexing.dao.metaalert.MetaAlertStatus; -import org.apache.metron.indexing.dao.metaalert.MetaScores; +import org.apache.metron.indexing.dao.metaalert.MetaAlertUpdateDao; import org.apache.metron.indexing.dao.search.FieldType; import org.apache.metron.indexing.dao.search.GetRequest; import org.apache.metron.indexing.dao.search.GroupRequest; @@ -46,20 +44,19 @@ import org.apache.metron.indexing.dao.search.InvalidCreateException; import org.apache.metron.indexing.dao.search.InvalidSearchException; import org.apache.metron.indexing.dao.search.SearchRequest; import org.apache.metron.indexing.dao.search.SearchResponse; -import org.apache.metron.indexing.dao.search.SearchResult; import org.apache.metron.indexing.dao.update.CommentAddRemoveRequest; import org.apache.metron.indexing.dao.update.Document; import org.apache.metron.indexing.dao.update.OriginalNotFoundException; import org.apache.metron.indexing.dao.update.PatchRequest; import org.apache.metron.indexing.dao.update.ReplaceRequest; -import org.json.simple.JSONArray; -import org.json.simple.JSONObject; public class InMemoryMetaAlertDao implements MetaAlertDao { - public static Map<String, Collection<String>> METAALERT_STORE = new HashMap<>(); + public static final String METAALERT_INDEX = "metaalert_index"; private IndexDao indexDao; + private MetaAlertRetrieveLatestDao metaAlertRetrieveLatestDao; + private MetaAlertUpdateDao metaAlertUpdateDao; private int pageSize = 10; /** @@ -97,6 +94,24 @@ public class InMemoryMetaAlertDao implements MetaAlertDao { @Override public void init(IndexDao indexDao, Optional<String> threatSort) { this.indexDao = indexDao; + this.metaAlertRetrieveLatestDao = new InMemoryMetaAlertRetrieveLatestDao(indexDao); + Supplier<Map<String, Object>> globalConfigSupplier = () -> new HashMap<>(); + MetaAlertConfig config = new MetaAlertConfig( + METAALERT_INDEX, + null, + globalConfigSupplier + ) { + @Override + protected String getDefaultThreatTriageField() { + return MetaAlertConstants.THREAT_FIELD_DEFAULT; + } + + @Override + protected String getDefaultSourceTypeField() { + return SENSOR_TYPE; + } + }; + this.metaAlertUpdateDao = new InMemoryMetaAlertUpdateDao(indexDao, metaAlertRetrieveLatestDao, config, -1); // Ignore threatSort for test. } @@ -112,12 +127,12 @@ public class InMemoryMetaAlertDao implements MetaAlertDao { } @Override - public void update(Document update, Optional<String> index) throws IOException { - indexDao.update(update, index); + public Document update(Document update, Optional<String> index) throws IOException { + return indexDao.update(update, index); } @Override - public void batchUpdate(Map<Document, Optional<String>> updates) { + public Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) { throw new UnsupportedOperationException("InMemoryMetaAlertDao can't do bulk updates"); } @@ -128,19 +143,23 @@ public class InMemoryMetaAlertDao implements MetaAlertDao { } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) { + public Document addCommentToAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + return null; } @Override @@ -149,15 +168,15 @@ public class InMemoryMetaAlertDao implements MetaAlertDao { } @Override - public void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, + public Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, Optional<Long> timestamp) throws OriginalNotFoundException, IOException { - indexDao.patch(retrieveLatestDao, request, timestamp); + return indexDao.patch(retrieveLatestDao, request, timestamp); } @Override - public void replace(ReplaceRequest request, Optional<Long> timestamp) throws IOException { - indexDao.replace(request, timestamp); + public Document replace(ReplaceRequest request, Optional<Long> timestamp) throws IOException { + return indexDao.replace(request, timestamp); } @Override @@ -174,145 +193,29 @@ public class InMemoryMetaAlertDao implements MetaAlertDao { @SuppressWarnings("unchecked") @Override - public MetaAlertCreateResponse createMetaAlert(MetaAlertCreateRequest request) - throws InvalidCreateException { - List<GetRequest> 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<Double> threatScores = new ArrayList<>(); - Collection<String> 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<SearchResult> 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); } @Override - public boolean addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) { - Collection<String> currentAlertGuids = METAALERT_STORE.get(metaAlertGuid); - if (currentAlertGuids == null) { - return false; - } - Collection<String> alertGuids = alertRequests.stream().map(GetRequest::getGuid) - .collect(Collectors.toSet()); - boolean added = currentAlertGuids.addAll(alertGuids); - if (added) { - METAALERT_STORE.put(metaAlertGuid, currentAlertGuids); - } - return added; + public Document addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) throws IOException { + return metaAlertUpdateDao.addAlertsToMetaAlert(metaAlertGuid, alertRequests); } @Override - public boolean removeAlertsFromMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) { - Collection<String> currentAlertGuids = METAALERT_STORE.get(metaAlertGuid); - if (currentAlertGuids == null) { - return false; - } - Collection<String> alertGuids = alertRequests.stream().map(GetRequest::getGuid) - .collect(Collectors.toSet()); - boolean removed = currentAlertGuids.removeAll(alertGuids); - if (removed) { - METAALERT_STORE.put(metaAlertGuid, currentAlertGuids); - } - return removed; + public Document removeAlertsFromMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) throws IOException { + return metaAlertUpdateDao.removeAlertsFromMetaAlert(metaAlertGuid, alertRequests); } @SuppressWarnings("unchecked") @Override - public boolean updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) + public Document updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) throws IOException { - boolean statusChanged = false; - List<String> metaAlerts = InMemoryDao.BACKING_STORE.get(getMetaAlertIndex()); - for (String metaAlert : metaAlerts) { - JSONObject metaAlertJSON = JSONUtils.INSTANCE.load(metaAlert, JSONObject.class); - if (metaAlertGuid.equals(metaAlertJSON.get(GUID))) { - statusChanged = !status.getStatusString() - .equals(metaAlertJSON.get(MetaAlertConstants.STATUS_FIELD)); - if (statusChanged) { - metaAlertJSON.put(MetaAlertConstants.STATUS_FIELD, status.getStatusString()); - metaAlerts.remove(metaAlert); - metaAlerts.add(metaAlertJSON.toJSONString()); - InMemoryDao.BACKING_STORE.put(getMetaAlertIndex(), metaAlerts); - } - break; - } - } - return statusChanged; - } - - public int getPageSize() { - return pageSize; - } - - public void setPageSize(int pageSize) { - this.pageSize = pageSize; - } - - public String getMetAlertSensorName() { - return MetaAlertConstants.METAALERT_TYPE; - } - - public String getMetaAlertIndex() { - return "metaalert_index"; + return metaAlertUpdateDao.updateMetaAlertStatus(metaAlertGuid, status); } public static void clear() { InMemoryDao.clear(); - METAALERT_STORE.clear(); } } http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertUpdateDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertUpdateDao.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertUpdateDao.java new file mode 100644 index 0000000..53564b0 --- /dev/null +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/InMemoryMetaAlertUpdateDao.java @@ -0,0 +1,91 @@ +/* + * 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 { + + private IndexDao indexDao; + + public InMemoryMetaAlertUpdateDao( + IndexDao indexDao, + MetaAlertRetrieveLatestDao retrieveLatestDao, + MetaAlertConfig config, + int pageSize + ) { + super(indexDao, retrieveLatestDao, config); + this.indexDao = indexDao; + } + + @SuppressWarnings("unchecked") + @Override + public Document createMetaAlert(MetaAlertCreateRequest request) throws InvalidCreateException, IOException { + List<GetRequest> alertRequests = request.getAlerts(); + if (alertRequests.isEmpty()) { + return null; + } + // Retrieve the documents going into the meta alert and build it + Iterable<Document> alerts = indexDao.getAllLatest(alertRequests); + + Document metaAlert = buildCreateDocument(alerts, request.getGroups(), + MetaAlertConstants.ALERT_FIELD); + + metaAlert.getDocument() + .put(getConfig().getSourceTypeField(), MetaAlertConstants.METAALERT_TYPE); + + return metaAlert; + } + + @Override + public Document update(Document update, Optional<String> index) throws IOException { + return indexDao.update(update, index); + } + + @Override + public Document addCommentToAlert(CommentAddRemoveRequest request) throws IOException { + return null; + } + + @Override + public Document removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { + return null; + } + + @Override + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException { + return null; + } + + @Override + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException { + return null; + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/MultiIndexDaoTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/MultiIndexDaoTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/MultiIndexDaoTest.java new file mode 100644 index 0000000..dad6a52 --- /dev/null +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/MultiIndexDaoTest.java @@ -0,0 +1,96 @@ +/* + * 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.update.CommentAddRemoveRequest; +import org.apache.metron.indexing.dao.update.Document; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.IOException; +import java.util.HashMap; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class MultiIndexDaoTest { + @Rule + public final ExpectedException exception = ExpectedException.none(); + + private MultiIndexDao multiIndexDao; + private IndexDao dao1; + private IndexDao dao2; + + @Before + public void setup() { + dao1 = mock(IndexDao.class); + dao2 = mock(IndexDao.class); + multiIndexDao = new MultiIndexDao(dao1, dao2); + } + + @Test + public void getLatestShouldReturnLatestAlert() throws Exception { + Document document1 = new Document(new HashMap<>(), "guid", "bro", 1L); + Document document2 = new Document(new HashMap<>(), "guid", "bro", 2L); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + when(dao1.getLatest("guid", "bro")).thenReturn(document1); + when(dao2.getLatest("guid", "bro")).thenReturn(document2); + + + Document expected = new Document(new HashMap<>(), "guid", "bro", 2L); + Assert.assertEquals(expected, multiIndexDao.getLatest("guid", "bro")); + } + + @Test + public void addCommentShouldAddCommentToAlert() throws Exception { + Document latest = mock(Document.class); + Document document1 = new Document(new HashMap<>(), "guid", "bro", 1L); + Document document2 = new Document(new HashMap<>(), "guid", "bro", 2L); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + when(dao1.addCommentToAlert(request, latest)).thenReturn(document1); + when(dao2.addCommentToAlert(request, latest)).thenReturn(document2); + + + Document expected = new Document(new HashMap<>(), "guid", "bro", 2L); + Assert.assertEquals(expected, multiIndexDao.addCommentToAlert(request, latest)); + } + + @Test + public void removeCommentShouldRemoveCommentFromAlert() throws Exception { + Document latest = mock(Document.class); + Document document1 = new Document(new HashMap<>(), "guid", "bro", 1L); + Document document2 = new Document(new HashMap<>(), "guid", "bro", 2L); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + when(dao1.removeCommentFromAlert(request, latest)).thenReturn(document1); + when(dao2.removeCommentFromAlert(request, latest)).thenReturn(document2); + + + Document expected = new Document(new HashMap<>(), "guid", "bro", 2L); + Assert.assertEquals(expected, multiIndexDao.removeCommentFromAlert(request, latest)); + } +} http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateDaoTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateDaoTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateDaoTest.java new file mode 100644 index 0000000..bbe7fa8 --- /dev/null +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateDaoTest.java @@ -0,0 +1,74 @@ +/* + * 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.update.CommentAddRemoveRequest; +import org.apache.metron.indexing.dao.update.Document; +import org.apache.metron.indexing.dao.update.UpdateDao; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.io.IOException; +import java.util.HashMap; + +/** + * The tests in this class are common among all UpdateDao implementations. + */ +public abstract class UpdateDaoTest { + + @Rule + public final ExpectedException exception = ExpectedException.none(); + + @Test + public void addCommentShouldThrowExceptionOnMissingAlert() throws Exception { + exception.expect(IOException.class); + exception.expectMessage("Unable to add comment. Document with guid guid cannot be found."); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + + getUpdateDao().addCommentToAlert(request, null); + } + + @Test + public void removeCommentShouldThrowExceptionOnMissingAlert() throws Exception { + exception.expect(IOException.class); + exception.expectMessage("Unable to remove comment. Document with guid guid cannot be found."); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + + getUpdateDao().removeCommentFromAlert(request, null); + } + + @Test + public void removeCommentShouldThrowExceptionOnEmptyComments() throws Exception { + exception.expect(IOException.class); + exception.expectMessage("Unable to remove comment. Document with guid guid has no comments."); + + CommentAddRemoveRequest request = new CommentAddRemoveRequest(); + request.setGuid("guid"); + Document latest = new Document(new HashMap<>(), "guid", "bro", System.currentTimeMillis()); + + getUpdateDao().removeCommentFromAlert(request, latest); + } + + public abstract UpdateDao getUpdateDao(); +} http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateIntegrationTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateIntegrationTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateIntegrationTest.java index 1e35523..ef9714e 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateIntegrationTest.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/UpdateIntegrationTest.java @@ -18,7 +18,6 @@ import static org.apache.metron.indexing.dao.IndexDao.COMMENTS_FIELD; import java.io.IOException; import java.util.ArrayList; -import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -99,13 +98,14 @@ public abstract class UpdateIntegrationTest { put("new-field", "metron"); }}; String guid = "" + message0.get(Constants.GUID); - getDao().replace(new ReplaceRequest(){{ + Document update = getDao().replace(new ReplaceRequest(){{ setReplacement(message0); setGuid(guid); setSensorType(SENSOR_NAME); setIndex(getIndexName()); }}, Optional.empty()); + Assert.assertEquals(message0, update.getDocument()); Assert.assertEquals(1, getMockHTable().size()); findUpdatedDoc(message0, guid, SENSOR_NAME); { @@ -138,12 +138,13 @@ public abstract class UpdateIntegrationTest { put("new-field", "metron2"); }}; String guid = "" + message0.get(Constants.GUID); - getDao().replace(new ReplaceRequest(){{ + Document update = getDao().replace(new ReplaceRequest(){{ setReplacement(message0); setGuid(guid); setSensorType(SENSOR_NAME); setIndex(getIndexName()); }}, Optional.empty()); + Assert.assertEquals(message0, update.getDocument()); Assert.assertEquals(1, getMockHTable().size()); Document doc = getDao().getLatest(guid, SENSOR_NAME); Assert.assertEquals(message0, doc.getDocument()); @@ -184,33 +185,40 @@ public abstract class UpdateIntegrationTest { fields.put("source.type", SENSOR_NAME); Document document = new Document(fields, "add_comment", SENSOR_NAME, 1526306463050L); - getDao().update(document, Optional.of(SENSOR_NAME)); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); - - addAlertComment("add_comment", "New Comment", "test_user", 1526306463050L); - // Ensure we have the first comment + { + Document update = getDao().update(document, Optional.of(SENSOR_NAME)); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } ArrayList<AlertComment> comments = new ArrayList<>(); - comments.add(new AlertComment("New Comment", "test_user", 1526306463050L)); - document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( - Collectors.toList())); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); - - List<Map<String, Object>> patchList = new ArrayList<>(); - Map<String, Object> patch = new HashMap<>(); - patch.put("op", "add"); - patch.put("path", "/project"); - patch.put("value", "metron"); - patchList.add(patch); + { + Document update = addAlertComment("add_comment", "New Comment", "test_user", 1526306463050L); + // Ensure we have the first comment + comments.add(new AlertComment("New Comment", "test_user", 1526306463050L)); + document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( + Collectors.toList())); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } + { + List<Map<String, Object>> patchList = new ArrayList<>(); + Map<String, Object> patch = new HashMap<>(); + patch.put("op", "add"); + patch.put("path", "/project"); + patch.put("value", "metron"); + patchList.add(patch); - PatchRequest pr = new PatchRequest(); - pr.setGuid("add_comment"); - pr.setIndex(SENSOR_NAME); - pr.setSensorType(SENSOR_NAME); - pr.setPatch(patchList); - getDao().patch(getDao(), pr, Optional.of(new Date().getTime())); + PatchRequest pr = new PatchRequest(); + pr.setGuid("add_comment"); + pr.setIndex(SENSOR_NAME); + pr.setSensorType(SENSOR_NAME); + pr.setPatch(patchList); + Document update = getDao().patch(getDao(), pr, Optional.of(1526306463050L)); - document.getDocument().put("project", "metron"); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + document.getDocument().put("project", "metron"); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } } @Test @@ -221,48 +229,60 @@ public abstract class UpdateIntegrationTest { fields.put("source.type", SENSOR_NAME); Document document = new Document(fields, "add_comment", SENSOR_NAME, 1526401584951L); - getDao().update(document, Optional.of(SENSOR_NAME)); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); - - addAlertComment("add_comment", "New Comment", "test_user", 1526401584951L); - // Ensure we have the first comment + { + Document update = getDao().update(document, Optional.of(SENSOR_NAME)); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } ArrayList<AlertComment> comments = new ArrayList<>(); - comments.add(new AlertComment("New Comment", "test_user", 1526401584951L)); - document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( - Collectors.toList())); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); - - addAlertComment("add_comment", "New Comment 2", "test_user_2", 1526401584952L); - // Ensure we have the second comment - comments.add(new AlertComment("New Comment 2", "test_user_2", 1526401584952L)); - document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( - Collectors.toList())); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); - - removeAlertComment("add_comment", "New Comment 2", "test_user_2", 1526401584952L); - // Ensure we only have the first comments - comments = new ArrayList<>(); - comments.add(new AlertComment(commentOne)); - document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( - Collectors.toList())); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + { + Document update = addAlertComment("add_comment", "New Comment", "test_user", 1526401584951L); + // Ensure we have the first comment - removeAlertComment("add_comment", "New Comment", "test_user", 1526401584951L); - // Ensure we have no comments - document.getDocument().remove(COMMENTS_FIELD); - findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + comments.add(new AlertComment("New Comment", "test_user", 1526401584951L)); + document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( + Collectors.toList())); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } + { + Document update = addAlertComment("add_comment", "New Comment 2", "test_user_2", 1526401584952L); + // Ensure we have the second comment + comments.add(new AlertComment("New Comment 2", "test_user_2", 1526401584952L)); + document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( + Collectors.toList())); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } + { + Document update = removeAlertComment("add_comment", "New Comment 2", "test_user_2", 1526401584952L); + // Ensure we only have the first comments + comments = new ArrayList<>(); + comments.add(new AlertComment(commentOne)); + document.getDocument().put(COMMENTS_FIELD, comments.stream().map(AlertComment::asMap).collect( + Collectors.toList())); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } + { + Document update = removeAlertComment("add_comment", "New Comment", "test_user", 1526401584951L); + // Ensure we have no comments + document.getDocument().remove(COMMENTS_FIELD); + Assert.assertEquals(document, update); + findUpdatedDoc(document.getDocument(), "add_comment", SENSOR_NAME); + } } - protected void addAlertComment(String guid, String comment, String username, long timestamp) + protected Document addAlertComment(String guid, String comment, String username, long timestamp) throws IOException { CommentAddRemoveRequest request = buildAlertRequest(guid, comment, username, timestamp); - getDao().addCommentToAlert(request); + return getDao().addCommentToAlert(request); } - protected void removeAlertComment(String guid, String comment, String username, long timestamp) + protected Document removeAlertComment(String guid, String comment, String username, long timestamp) throws IOException { CommentAddRemoveRequest request = buildAlertRequest(guid, comment, username, timestamp); - getDao().removeCommentFromAlert(request); + return getDao().removeCommentFromAlert(request); } private CommentAddRemoveRequest buildAlertRequest(String guid, String comment, String username, http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java index f754b81..7e28853 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/MetaAlertIntegrationTest.java @@ -278,11 +278,40 @@ public abstract class MetaAlertIntegrationTest { }}); setGroups(Collections.singletonList("group")); }}; - MetaAlertCreateResponse metaAlertCreateResponse = metaDao + + Document actualMetaAlert = metaDao .createMetaAlert(metaAlertCreateRequest); + + // Build expected metaAlert after alerts are added + Map<String, Object> expectedMetaAlert = new HashMap<>(); + + expectedMetaAlert.put(Constants.GUID, actualMetaAlert.getGuid()); + expectedMetaAlert.put(getSourceTypeField(), METAALERT_TYPE); + expectedMetaAlert.put(STATUS_FIELD, MetaAlertStatus.ACTIVE.getStatusString()); + // Verify the proper alerts were added + @SuppressWarnings("unchecked") + List<Map<String, Object>> metaAlertAlerts = new ArrayList<>(); + // Alert 0 is already in the metaalert. Add alerts 1 and 2. + Map<String, Object> expectedAlert1 = alerts.get(1); + expectedAlert1.put(METAALERT_FIELD, Collections.singletonList(actualMetaAlert.getGuid())); + metaAlertAlerts.add(expectedAlert1); + Map<String, Object> expectedAlert2 = alerts.get(2); + expectedAlert2.put(METAALERT_FIELD, Collections.singletonList(actualMetaAlert.getGuid())); + metaAlertAlerts.add(expectedAlert2); + expectedMetaAlert.put(ALERT_FIELD, metaAlertAlerts); + + // Verify the counts were properly updated + expectedMetaAlert.put("average", 1.5d); + expectedMetaAlert.put("min", 1.0d); + expectedMetaAlert.put("median", 1.5d); + expectedMetaAlert.put("max", 2.0d); + expectedMetaAlert.put("count", 2); + expectedMetaAlert.put("sum", 3.0d); + expectedMetaAlert.put(getThreatTriageField(), 3.0d); { // Verify metaAlert was created - findCreatedDoc(metaAlertCreateResponse.getGuid(), METAALERT_TYPE); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); + findCreatedDoc(actualMetaAlert.getGuid(), METAALERT_TYPE); } { // Verify alert 0 was not updated with metaalert field @@ -294,14 +323,14 @@ public abstract class MetaAlertIntegrationTest { // Verify alert 1 was properly updated with metaalert field Map<String, Object> expectedAlert = new HashMap<>(alerts.get(1)); expectedAlert - .put(METAALERT_FIELD, Collections.singletonList(metaAlertCreateResponse.getGuid())); + .put(METAALERT_FIELD, Collections.singletonList(actualMetaAlert.getGuid())); findUpdatedDoc(expectedAlert, "message_1", SENSOR_NAME); } { // Verify alert 2 was properly updated with metaalert field Map<String, Object> expectedAlert = new HashMap<>(alerts.get(2)); expectedAlert - .put(METAALERT_FIELD, Collections.singletonList(metaAlertCreateResponse.getGuid())); + .put(METAALERT_FIELD, Collections.singletonList(actualMetaAlert.getGuid())); findUpdatedDoc(expectedAlert, "message_2", SENSOR_NAME); } } @@ -355,17 +384,19 @@ public abstract class MetaAlertIntegrationTest { { // Verify alerts were successfully added to the meta alert - Assert.assertTrue(metaDao.addAlertsToMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_1", SENSOR_NAME), - new GetRequest("message_2", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.addAlertsToMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_1", SENSOR_NAME), + new GetRequest("message_2", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } { // Verify False when alerts are already in a meta alert and no new alerts are added - Assert.assertFalse(metaDao.addAlertsToMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_0", SENSOR_NAME), - new GetRequest("message_1", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.addAlertsToMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_0", SENSOR_NAME), + new GetRequest("message_1", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } @@ -385,9 +416,10 @@ public abstract class MetaAlertIntegrationTest { expectedMetaAlert.put("sum", 6.0d); expectedMetaAlert.put(getThreatTriageField(), 6.0d); - Assert.assertTrue(metaDao.addAlertsToMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_2", SENSOR_NAME), - new GetRequest("message_3", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.addAlertsToMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_2", SENSOR_NAME), + new GetRequest("message_3", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } } @@ -437,17 +469,19 @@ public abstract class MetaAlertIntegrationTest { { // Verify a list of alerts are removed from a meta alert - Assert.assertTrue(metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_0", SENSOR_NAME), - new GetRequest("message_1", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_0", SENSOR_NAME), + new GetRequest("message_1", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } { // Verify False when alerts are not present in a meta alert and no alerts are removed - Assert.assertFalse(metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_0", SENSOR_NAME), - new GetRequest("message_1", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_0", SENSOR_NAME), + new GetRequest("message_1", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } @@ -466,9 +500,10 @@ public abstract class MetaAlertIntegrationTest { expectedMetaAlert.put("sum", 3.0d); expectedMetaAlert.put(getThreatTriageField(), 3.0d); - Assert.assertTrue(metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays - .asList(new GetRequest("message_0", SENSOR_NAME), - new GetRequest("message_2", SENSOR_NAME)))); + Document actualMetaAlert = metaDao.removeAlertsFromMetaAlert("meta_alert", Arrays + .asList(new GetRequest("message_0", SENSOR_NAME), + new GetRequest("message_2", SENSOR_NAME))); + assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); } @@ -587,11 +622,11 @@ public abstract class MetaAlertIntegrationTest { { // Verify status changed to inactive and child alerts are updated - Assert.assertTrue(metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.INACTIVE)); - Map<String, Object> expectedMetaAlert = new HashMap<>(metaAlert); expectedMetaAlert.put(STATUS_FIELD, MetaAlertStatus.INACTIVE.getStatusString()); + Document actualMetaAlert = metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.INACTIVE); + Assert.assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); for (int i = 0; i < numChildAlerts; ++i) { @@ -610,11 +645,11 @@ public abstract class MetaAlertIntegrationTest { { // Verify status changed to active and child alerts are updated - Assert.assertTrue(metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.ACTIVE)); - Map<String, Object> expectedMetaAlert = new HashMap<>(metaAlert); expectedMetaAlert.put(STATUS_FIELD, MetaAlertStatus.ACTIVE.getStatusString()); + Document actualMetaAlert = metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.ACTIVE); + Assert.assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); for (int i = 0; i < numChildAlerts; ++i) { @@ -629,11 +664,15 @@ public abstract class MetaAlertIntegrationTest { // Make sure to handle the guid offset from creation findUpdatedDoc(expectedAlert, "message_" + (i + numChildAlerts), SENSOR_NAME); } - + } + { { // Verify status changed to current status has no effect - Assert.assertFalse(metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.ACTIVE)); + Map<String, Object> expectedMetaAlert = new HashMap<>(metaAlert); + expectedMetaAlert.put(STATUS_FIELD, MetaAlertStatus.ACTIVE.getStatusString()); + Document actualMetaAlert = metaDao.updateMetaAlertStatus("meta_alert", MetaAlertStatus.ACTIVE); + Assert.assertEquals(expectedMetaAlert, actualMetaAlert.getDocument()); findUpdatedDoc(expectedMetaAlert, "meta_alert", METAALERT_TYPE); for (int i = 0; i < numChildAlerts; ++i) { @@ -985,6 +1024,30 @@ public abstract class MetaAlertIntegrationTest { throw new OriginalNotFoundException("Count not find guids after " + MAX_RETRIES + "tries"); } + @SuppressWarnings("unchecked") + protected void assertEquals(Map<String, Object> expected, Map<String, Object> actual) { + Assert.assertEquals(expected.get(Constants.GUID), actual.get(Constants.GUID)); + Assert.assertEquals(expected.get(getSourceTypeField()), actual.get(getSourceTypeField())); + Double actualThreatTriageField = actual.get(getThreatTriageField()) instanceof Float ? + ((Float) actual.get(getThreatTriageField())).doubleValue() : (Double) actual.get(getThreatTriageField()); + Assert.assertEquals(expected.get(getThreatTriageField()), actualThreatTriageField); + + List<Map<String, Object>> expectedAlerts = (List<Map<String, Object>>) expected.get(ALERT_FIELD); + List<Map<String, Object>> actualAlerts = (List<Map<String, Object>>) actual.get(ALERT_FIELD); + expectedAlerts.sort(Comparator.comparing(o -> ((String) o.get(Constants.GUID)))); + actualAlerts.sort(Comparator.comparing(o -> ((String) o.get(Constants.GUID)))); + Assert.assertEquals(expectedAlerts, actualAlerts); + Assert.assertEquals(expected.get(STATUS_FIELD), actual.get(STATUS_FIELD)); + Assert.assertEquals(expected.get("average"), actual.get("average")); + Assert.assertEquals(expected.get("min"), actual.get("min")); + Assert.assertEquals(expected.get("median"), actual.get("median")); + Assert.assertEquals(expected.get("max"), actual.get("max")); + Integer actualCountField = actual.get("count") instanceof Long ? ((Long) actual.get("count")).intValue() : + (Integer) actual.get("count"); + Assert.assertEquals(expected.get("count"), actualCountField); + Assert.assertEquals(expected.get("sum"), actual.get("sum")); + } + protected List<Map<String, Object>> buildAlerts(int count) { List<Map<String, Object>> inputData = new ArrayList<>(); for (int i = 0; i < count; ++i) { http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDaoTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDaoTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDaoTest.java index 5a70636..ec241e4 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDaoTest.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/dao/metaalert/lucene/AbstractLuceneMetaAlertUpdateDaoTest.java @@ -54,12 +54,10 @@ import org.apache.metron.indexing.dao.RetrieveLatestDao; 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.MetaAlertCreateResponse; import org.apache.metron.indexing.dao.metaalert.MetaAlertRetrieveLatestDao; import org.apache.metron.indexing.dao.metaalert.MetaAlertStatus; import org.apache.metron.indexing.dao.metaalert.MetaScores; import org.apache.metron.indexing.dao.search.GetRequest; -import org.apache.metron.indexing.dao.search.InvalidSearchException; import org.apache.metron.indexing.dao.update.CommentAddRemoveRequest; import org.apache.metron.indexing.dao.update.Document; import org.apache.metron.indexing.dao.update.PatchRequest; @@ -157,43 +155,39 @@ public class AbstractLuceneMetaAlertUpdateDaoTest { } @Override - public void update(Document update, Optional<String> index) { + public Document update(Document update, Optional<String> index) { + return null; } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) { + public Document addCommentToAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request) { + return null; } @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) { + return null; } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) { + return null; } @Override - public void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, + public Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, Optional<Long> timestamp) { - } - - @Override - public MetaAlertCreateResponse createMetaAlert(MetaAlertCreateRequest request) { return null; } @Override - public boolean addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) { - return false; - } - - @Override - public boolean updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) { - return false; + public Document createMetaAlert(MetaAlertCreateRequest request) { + return null; } } @@ -762,6 +756,30 @@ public class AbstractLuceneMetaAlertUpdateDaoTest { UUID.fromString((String) actualDocument.get(Constants.GUID)); } + @Test + public void addAlertsToMetaAlertShouldThrowExceptionOnMissingMetaAlert() throws Exception { + thrown.expect(IOException.class); + thrown.expectMessage("Unable to add alerts to meta alert. Meta alert with guid some_guid cannot be found."); + + dao.addAlertsToMetaAlert("some_guid", new ArrayList<>()); + } + + @Test + public void removeAlertsFromMetaAlertShouldThrowExceptionOnMissingMetaAlert() throws Exception { + thrown.expect(IOException.class); + thrown.expectMessage("Unable to remove alerts from meta alert. Meta alert with guid some_guid cannot be found."); + + dao.removeAlertsFromMetaAlert("some_guid", new ArrayList<>()); + } + + @Test + public void updateMetaAlertStatusShouldThrowExceptionOnMissingMetaAlert() throws Exception { + thrown.expect(IOException.class); + thrown.expectMessage("Unable to update meta alert status. Meta alert with guid some_guid cannot be found."); + + dao.updateMetaAlertStatus("some_guid", MetaAlertStatus.INACTIVE); + } + // Utility method to manage comparing update maps protected boolean updatesMapEquals(Map<Document, Optional<String>> expected, Map<Document, Optional<String>> actual) { http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java index 73a9077..8eaa8f4 100644 --- a/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java +++ b/metron-platform/metron-indexing/src/test/java/org/apache/metron/indexing/integration/HBaseDaoIntegrationTest.java @@ -35,14 +35,13 @@ import org.apache.metron.hbase.mock.MockHTable; import org.apache.metron.indexing.dao.AccessConfig; import org.apache.metron.indexing.dao.HBaseDao; import org.apache.metron.indexing.dao.IndexDao; -import org.apache.metron.indexing.dao.MultiIndexDao; import org.apache.metron.indexing.dao.UpdateIntegrationTest; import org.apache.metron.indexing.dao.search.AlertComment; import org.apache.metron.indexing.dao.search.GetRequest; import org.apache.metron.indexing.dao.update.Document; import org.junit.After; import org.junit.Assert; -import org.junit.BeforeClass; +import org.junit.Before; import org.junit.Test; public class HBaseDaoIntegrationTest extends UpdateIntegrationTest { @@ -61,8 +60,8 @@ public class HBaseDaoIntegrationTest extends UpdateIntegrationTest { 0x54,0x79,0x70,0x65 }; - @BeforeClass - public static void startHBase() throws Exception { + @Before + public void startHBase() throws Exception { AccessConfig accessConfig = new AccessConfig(); accessConfig.setMaxSearchResults(1000); accessConfig.setMaxSearchGroups(1000); http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrDao.java b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrDao.java index a840bb4..e6906f3 100644 --- a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrDao.java +++ b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrDao.java @@ -124,30 +124,30 @@ public class SolrDao implements IndexDao { } @Override - public void update(Document update, Optional<String> index) throws IOException { - this.solrUpdateDao.update(update, index); + public Document update(Document update, Optional<String> index) throws IOException { + return this.solrUpdateDao.update(update, index); } @Override - public void batchUpdate(Map<Document, Optional<String>> updates) throws IOException { - this.solrUpdateDao.batchUpdate(updates); + public Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) throws IOException { + return this.solrUpdateDao.batchUpdate(updates); } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) throws IOException { - this.solrUpdateDao.addCommentToAlert(request); + public Document addCommentToAlert(CommentAddRemoveRequest request) throws IOException { + return this.solrUpdateDao.addCommentToAlert(request); } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { - this.solrUpdateDao.removeCommentFromAlert(request); + public Document removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { + return this.solrUpdateDao.removeCommentFromAlert(request); } @Override - public void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, + public Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, Optional<Long> timestamp) throws OriginalNotFoundException, IOException { - solrUpdateDao.patch(retrieveLatestDao, request, timestamp); + return solrUpdateDao.patch(retrieveLatestDao, request, timestamp); } @Override @@ -156,15 +156,15 @@ public class SolrDao implements IndexDao { } @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - this.solrUpdateDao.addCommentToAlert(request, latest); + return this.solrUpdateDao.addCommentToAlert(request, latest); } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - this.solrUpdateDao.removeCommentFromAlert(request, latest); + return this.solrUpdateDao.removeCommentFromAlert(request, latest); } /** http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertDao.java b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertDao.java index 4748315..8ef9484 100644 --- a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertDao.java +++ b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertDao.java @@ -33,7 +33,6 @@ import org.apache.metron.indexing.dao.RetrieveLatestDao; 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.MetaAlertCreateResponse; import org.apache.metron.indexing.dao.metaalert.MetaAlertDao; import org.apache.metron.indexing.dao.metaalert.MetaAlertStatus; import org.apache.metron.indexing.dao.search.FieldType; @@ -190,20 +189,20 @@ public class SolrMetaAlertDao implements MetaAlertDao { } @Override - public void update(Document update, Optional<String> index) throws IOException { - metaAlertUpdateDao.update(update, index); + public Document update(Document update, Optional<String> index) throws IOException { + return metaAlertUpdateDao.update(update, index); } @Override - public void batchUpdate(Map<Document, Optional<String>> updates) { - metaAlertUpdateDao.batchUpdate(updates); + public Map<Document, Optional<String>> batchUpdate(Map<Document, Optional<String>> updates) { + return metaAlertUpdateDao.batchUpdate(updates); } @Override - public void patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, + public Document patch(RetrieveLatestDao retrieveLatestDao, PatchRequest request, Optional<Long> timestamp) throws OriginalNotFoundException, IOException { - metaAlertUpdateDao.patch(retrieveLatestDao, request, timestamp); + return metaAlertUpdateDao.patch(retrieveLatestDao, request, timestamp); } @Override @@ -212,46 +211,46 @@ public class SolrMetaAlertDao implements MetaAlertDao { } @Override - public MetaAlertCreateResponse createMetaAlert(MetaAlertCreateRequest request) + public Document createMetaAlert(MetaAlertCreateRequest request) throws InvalidCreateException, IOException { return metaAlertUpdateDao.createMetaAlert(request); } @Override - public boolean addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) + public Document addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) throws IOException { return metaAlertUpdateDao.addAlertsToMetaAlert(metaAlertGuid, alertRequests); } @Override - public boolean removeAlertsFromMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) + public Document removeAlertsFromMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) throws IOException { return metaAlertUpdateDao.removeAlertsFromMetaAlert(metaAlertGuid, alertRequests); } @Override - public boolean updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) + public Document updateMetaAlertStatus(String metaAlertGuid, MetaAlertStatus status) throws IOException { return metaAlertUpdateDao.updateMetaAlertStatus(metaAlertGuid, status); } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) throws IOException { - solrDao.addCommentToAlert(request); + public Document addCommentToAlert(CommentAddRemoveRequest request) throws IOException { + return solrDao.addCommentToAlert(request); } - @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { - solrDao.removeCommentFromAlert(request); - } + @Override + public Document removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { + return solrDao.removeCommentFromAlert(request); + } - @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - solrDao.addCommentToAlert(request, latest); - } + @Override + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException { + return solrDao.addCommentToAlert(request, latest); + } - @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - solrDao.removeCommentFromAlert(request, latest); - } + @Override + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException { + return solrDao.removeCommentFromAlert(request, latest); + } } http://git-wip-us.apache.org/repos/asf/metron/blob/de533063/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertUpdateDao.java ---------------------------------------------------------------------- diff --git a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertUpdateDao.java b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertUpdateDao.java index 132d872..124d4be 100644 --- a/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertUpdateDao.java +++ b/metron-platform/metron-solr/src/main/java/org/apache/metron/solr/dao/SolrMetaAlertUpdateDao.java @@ -28,11 +28,9 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; -import org.apache.metron.common.Constants; 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.MetaAlertCreateResponse; import org.apache.metron.indexing.dao.metaalert.MetaAlertStatus; import org.apache.metron.indexing.dao.metaalert.MetaAlertUpdateDao; import org.apache.metron.indexing.dao.metaalert.MetaScores; @@ -71,7 +69,7 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp } @Override - public MetaAlertCreateResponse createMetaAlert(MetaAlertCreateRequest request) + public Document createMetaAlert(MetaAlertCreateRequest request) throws InvalidCreateException, IOException { List<GetRequest> alertRequests = request.getAlerts(); if (request.getAlerts().isEmpty()) { @@ -120,11 +118,8 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp // Kick off any updates. update(updates); - MetaAlertCreateResponse createResponse = new MetaAlertCreateResponse(); - createResponse.setCreated(true); - createResponse.setGuid(metaAlert.getGuid()); solrClient.commit(METAALERTS_COLLECTION); - return createResponse; + return metaAlert; } catch (IOException | SolrServerException e) { throw new InvalidCreateException("Unable to create meta alert", e); } @@ -135,10 +130,11 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp * Updates a document in Solr for a given collection. Collection is not optional for Solr. * @param update The update to be run * @param collection The index to be updated. Mandatory for Solr + * @return The updated document. * @throws IOException Thrown when an error occurs during the write. */ @Override - public void update(Document update, Optional<String> collection) throws IOException { + public Document update(Document update, Optional<String> collection) throws IOException { if (MetaAlertConstants.METAALERT_TYPE.equals(update.getSensorType())) { // We've been passed an update to the meta alert. throw new UnsupportedOperationException("Meta alerts cannot be directly updated"); @@ -181,28 +177,30 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp } catch (SolrServerException e) { throw new IOException("Unable to update document", e); } + + return update; } @Override - public void addCommentToAlert(CommentAddRemoveRequest request) throws IOException { - getUpdateDao().addCommentToAlert(request); + public Document addCommentToAlert(CommentAddRemoveRequest request) throws IOException { + return getUpdateDao().addCommentToAlert(request); } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { - getUpdateDao().removeCommentFromAlert(request); + public Document removeCommentFromAlert(CommentAddRemoveRequest request) throws IOException { + return getUpdateDao().removeCommentFromAlert(request); } @Override - public void addCommentToAlert(CommentAddRemoveRequest request, Document latest) + public Document addCommentToAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - getUpdateDao().addCommentToAlert(request, latest); + return getUpdateDao().addCommentToAlert(request, latest); } @Override - public void removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) + public Document removeCommentFromAlert(CommentAddRemoveRequest request, Document latest) throws IOException { - getUpdateDao().removeCommentFromAlert(request, latest); + return getUpdateDao().removeCommentFromAlert(request, latest); } protected boolean replaceAlertInMetaAlert(Document metaAlert, Document alert) { @@ -215,9 +213,8 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp } @Override - public boolean addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) - throws IOException { - boolean success; + public Document addAlertsToMetaAlert(String metaAlertGuid, List<GetRequest> alertRequests) + throws IOException, IllegalStateException { Document metaAlert = getRetrieveLatestDao() .getLatest(metaAlertGuid, MetaAlertConstants.METAALERT_TYPE); if (MetaAlertStatus.ACTIVE.getStatusString() @@ -225,7 +222,6 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp Iterable<Document> alerts = getRetrieveLatestDao().getAllLatest(alertRequests); Map<Document, Optional<String>> updates = buildAddAlertToMetaAlertUpdates(metaAlert, alerts); update(updates); - success = updates.size() != 0; } else { throw new IllegalStateException("Adding alerts to an INACTIVE meta alert is not allowed"); } @@ -234,6 +230,6 @@ public class SolrMetaAlertUpdateDao extends AbstractLuceneMetaAlertUpdateDao imp } catch (SolrServerException e) { throw new IOException("Unable to commit alerts to metaalert: " + metaAlertGuid, e); } - return success; + return metaAlert; } }