diff --git a/graylog2-server/src/main/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleService.java b/graylog2-server/src/main/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleService.java index fae8fed312b5..4fffe9984f54 100644 --- a/graylog2-server/src/main/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleService.java +++ b/graylog2-server/src/main/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleService.java @@ -111,7 +111,7 @@ public Collection loadAll() { @Override public void delete(String id) { - if (!scopedEntityMongoUtils.deleteById(id)) { + if (!scopedEntityMongoUtils.deleteById(id, false)) { log.error("Unable to delete rule {}", id); } clusterBus.post(RulesChangedEvent.deletedRuleId(id)); diff --git a/graylog2-server/src/main/java/org/graylog2/database/utils/ScopedEntityMongoUtils.java b/graylog2-server/src/main/java/org/graylog2/database/utils/ScopedEntityMongoUtils.java index 79cb2ec09329..a2c75c180730 100644 --- a/graylog2-server/src/main/java/org/graylog2/database/utils/ScopedEntityMongoUtils.java +++ b/graylog2-server/src/main/java/org/graylog2/database/utils/ScopedEntityMongoUtils.java @@ -69,7 +69,11 @@ public String create(T entity) { * @return true if a document was deleted, false otherwise. */ public boolean deleteById(String id) { - return deleteById(new ObjectId(id)); + return deleteById(new ObjectId(id), true); + } + + public boolean deleteById(String id, boolean checkMutability) { + return deleteById(new ObjectId(id), checkMutability); } /** @@ -78,11 +82,13 @@ public boolean deleteById(String id) { * @param id the document's id. * @return true if a document was deleted, false otherwise. */ - public boolean deleteById(ObjectId id) { + public boolean deleteById(ObjectId id, boolean checkMutability) { final T entity = Optional.ofNullable(collection.find(idEq(id)).first()) .orElseThrow(() -> new IllegalArgumentException("Entity not found")); ensureDeletability(entity); - ensureMutability(entity); + if (checkMutability) { + ensureMutability(entity); + } return collection.deleteOne(idEq(id)).getDeletedCount() > 0; } diff --git a/graylog2-server/src/test/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleServiceTest.java b/graylog2-server/src/test/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleServiceTest.java index 55bd5929fa01..a5b952a94b19 100644 --- a/graylog2-server/src/test/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleServiceTest.java +++ b/graylog2-server/src/test/java/org/graylog/plugins/pipelineprocessor/db/mongodb/MongoDbRuleServiceTest.java @@ -34,7 +34,10 @@ import java.util.Set; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; @ExtendWith(MongoDBExtension.class) @@ -60,6 +63,14 @@ void create() throws Exception { verify(clusterEventBus).post(eq(RulesChangedEvent.updatedRuleId(savedRule.id()))); } + @Test + void createSystemRule() throws Exception { + final var rule = systemRule(); + final var savedRule = ruleService.save(rule); + assertThat(ruleService.load(savedRule.id())).isEqualTo(rule.toBuilder().id(savedRule.id()).build()); + verify(clusterEventBus).post(eq(RulesChangedEvent.updatedRuleId(savedRule.id()))); + } + @Test void update() throws Exception { final var rule = dummyRule().toBuilder().id(new ObjectId().toHexString()).build(); @@ -68,6 +79,15 @@ void update() throws Exception { verify(clusterEventBus).post(eq(RulesChangedEvent.updatedRuleId(savedRule.id()))); } + @Test + void updateSystemRuleThrows() throws Exception { + final var rule = systemRule().toBuilder().id(new ObjectId().toHexString()).build(); + assertThatThrownBy(() -> ruleService.save(rule)) + .isInstanceOf(IllegalArgumentException.class) + .hasMessage("Immutable entity cannot be modified"); + verify(clusterEventBus, times(0)).post(any()); + } + @Test void loadByName() throws Exception { final var rule = dummyRule(); @@ -93,6 +113,15 @@ void delete() { verify(clusterEventBus).post(eq(RulesChangedEvent.deletedRuleId(rule.id()))); } + @Test + void deleteSystemRule() { + final var rule = ruleService.save(systemRule().toBuilder().title("title 2").build()); + assertThat(ruleService.loadAll()).hasSize(1); + ruleService.delete(rule.id()); + assertThat(ruleService.loadAll()).hasSize(0); + verify(clusterEventBus).post(eq(RulesChangedEvent.deletedRuleId(rule.id()))); + } + @Test void loadNamed() { final var rule1 = ruleService.save(dummyRule().toBuilder().title("title 1").build()); @@ -107,4 +136,8 @@ private static RuleDao dummyRule() { return RuleDao.builder().title("a title").source("a source").build(); } + private static RuleDao systemRule() { + return RuleDao.builder().scope(SystemPipelineRuleScope.NAME).title("a sysytem rule").source("a source").build(); + } + }