From 2f8f3a5a94e734ae1a61d4ea523d2cb236c3ff2e Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 11:19:27 +0100 Subject: [PATCH 1/8] handle system index set scoping --- .../entities/ScopedEntitiesModule.java | 2 + .../indexset/MongoIndexSetService.java | 12 +++- .../graylog2/migrations/MigrationsModule.java | 1 + ...20241212102900_IndexSetScopeMigration.java | 55 +++++++++++++++++++ 4 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 graylog2-server/src/main/java/org/graylog2/migrations/V20241212102900_IndexSetScopeMigration.java diff --git a/graylog2-server/src/main/java/org/graylog2/database/entities/ScopedEntitiesModule.java b/graylog2-server/src/main/java/org/graylog2/database/entities/ScopedEntitiesModule.java index a1348fdb2647..badab1cadac3 100644 --- a/graylog2-server/src/main/java/org/graylog2/database/entities/ScopedEntitiesModule.java +++ b/graylog2-server/src/main/java/org/graylog2/database/entities/ScopedEntitiesModule.java @@ -16,6 +16,7 @@ */ package org.graylog2.database.entities; +import org.graylog2.indexer.indexset.SystemIndexSetScope; import org.graylog2.plugin.PluginModule; public class ScopedEntitiesModule extends PluginModule { @@ -23,6 +24,7 @@ public class ScopedEntitiesModule extends PluginModule { protected void configure() { addEntityScope(DefaultEntityScope.class); + addEntityScope(SystemIndexSetScope.class); addSystemRestResource(EntityScopeResource.class); } diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java index eaeeb5aa9b56..9862222d3d9b 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java @@ -29,7 +29,9 @@ import jakarta.inject.Inject; import org.bson.types.ObjectId; import org.graylog2.database.MongoCollections; +import org.graylog2.database.entities.EntityScopeService; import org.graylog2.database.utils.MongoUtils; +import org.graylog2.database.utils.ScopedEntityMongoUtils; import org.graylog2.events.ClusterEventBus; import org.graylog2.indexer.indexset.events.IndexSetCreatedEvent; import org.graylog2.indexer.indexset.events.IndexSetDeletedEvent; @@ -56,6 +58,7 @@ public class MongoIndexSetService implements IndexSetService { public static final String FIELD_TITLE = "title"; private final MongoCollection collection; + private final ScopedEntityMongoUtils scopedEntityMongoUtils; private final MongoUtils mongoUtils; private final ClusterConfigService clusterConfigService; private final ClusterEventBus clusterEventBus; @@ -65,9 +68,12 @@ public class MongoIndexSetService implements IndexSetService { public MongoIndexSetService(MongoCollections mongoCollections, StreamService streamService, ClusterConfigService clusterConfigService, - ClusterEventBus clusterEventBus) { + ClusterEventBus clusterEventBus, + EntityScopeService entityScopeService) { this.collection = mongoCollections.collection(COLLECTION_NAME, IndexSetConfig.class); this.mongoUtils = mongoCollections.utils(this.collection); + this.scopedEntityMongoUtils = mongoCollections.scopedEntityUtils(collection, entityScopeService); + this.streamService = streamService; this.clusterConfigService = clusterConfigService; this.clusterEventBus = requireNonNull(clusterEventBus); @@ -156,8 +162,10 @@ public List searchByTitle(String searchString) { */ @Override public IndexSetConfig save(IndexSetConfig indexSetConfig) { + scopedEntityMongoUtils.ensureValidScope(indexSetConfig); String id = indexSetConfig.id(); if (id != null) { + scopedEntityMongoUtils.ensureMutability(indexSetConfig); collection.replaceOne(idEq(id), indexSetConfig, new ReplaceOptions().upsert(true)); } else { final InsertOneResult insertOneResult = collection.insertOne(indexSetConfig); @@ -193,7 +201,7 @@ public int delete(ObjectId id) { if (!isDeletable(id)) { return 0; } - int removedEntries = mongoUtils.deleteById(id) ? 1 : 0; + int removedEntries = scopedEntityMongoUtils.deleteById(id) ? 1 : 0; if (removedEntries > 0) { final IndexSetDeletedEvent deletedEvent = IndexSetDeletedEvent.create(id.toHexString()); clusterEventBus.post(deletedEvent); diff --git a/graylog2-server/src/main/java/org/graylog2/migrations/MigrationsModule.java b/graylog2-server/src/main/java/org/graylog2/migrations/MigrationsModule.java index 7f0db743c90d..3e11de89f4d6 100644 --- a/graylog2-server/src/main/java/org/graylog2/migrations/MigrationsModule.java +++ b/graylog2-server/src/main/java/org/graylog2/migrations/MigrationsModule.java @@ -71,5 +71,6 @@ protected void configure() { addMigration(V20240312140000_RemoveFieldTypeMappingsManagerRole.class); addMigration(V202404170856_UpdateIndexSetTemplates.class); addMigration(V20240927120300_DataNodeMigrationIndexSet.class); + addMigration(V20241212102900_IndexSetScopeMigration.class); } } diff --git a/graylog2-server/src/main/java/org/graylog2/migrations/V20241212102900_IndexSetScopeMigration.java b/graylog2-server/src/main/java/org/graylog2/migrations/V20241212102900_IndexSetScopeMigration.java new file mode 100644 index 000000000000..7161c5bbfe50 --- /dev/null +++ b/graylog2-server/src/main/java/org/graylog2/migrations/V20241212102900_IndexSetScopeMigration.java @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2020 Graylog, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the Server Side Public License, version 1, + * as published by MongoDB, Inc. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * Server Side Public License for more details. + * + * You should have received a copy of the Server Side Public License + * along with this program. If not, see + * . + */ +package org.graylog2.migrations; + +import jakarta.inject.Inject; +import org.graylog2.indexer.indexset.IndexSetService; +import org.graylog2.indexer.indexset.SystemIndexSetScope; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.ZonedDateTime; + +/** + * Make system index sets (regular==false) non-deletable by assigning SystemIndexSetScope + */ +public class V20241212102900_IndexSetScopeMigration extends Migration { + private static final Logger LOG = LoggerFactory.getLogger(V20241212102900_IndexSetScopeMigration.class); + + private final IndexSetService indexSetService; + + @Inject + public V20241212102900_IndexSetScopeMigration(final IndexSetService indexSetService) { + this.indexSetService = indexSetService; + } + + @Override + public ZonedDateTime createdAt() { + return ZonedDateTime.parse("2024-12-12T10:29:00Z"); + } + + @Override + public void upgrade() { + indexSetService.findAll().forEach(indexSetConfig -> { + if (!indexSetConfig.isRegularIndex() && !indexSetConfig.scope().equalsIgnoreCase(SystemIndexSetScope.NAME)) { + indexSetService.save(indexSetConfig.toBuilder().scope(SystemIndexSetScope.NAME).build()); + LOG.info("Successfully updated scope for index set: {}", indexSetConfig.title()); + } + }); + } + +} From 52110c0c9677fd8bd7798df3a461d9d503026fe9 Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 11:28:14 +0100 Subject: [PATCH 2/8] CL --- changelog/unreleased/pr-21174.toml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 changelog/unreleased/pr-21174.toml diff --git a/changelog/unreleased/pr-21174.toml b/changelog/unreleased/pr-21174.toml new file mode 100644 index 000000000000..ddc86d2ecfa2 --- /dev/null +++ b/changelog/unreleased/pr-21174.toml @@ -0,0 +1,5 @@ +type = "c" +message = "Handle scoping for index sets: System index sets cannot be deleted." + +pulls = ["21174"] +issues = ["Graylog2/graylog-plugin-enterprise#5904"] From 70e7ff0d7806b97bd09a1e3b34f0a95cc86f40d0 Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 12:25:57 +0100 Subject: [PATCH 3/8] unit tests --- .../indexset/MongoIndexSetService.java | 7 +- .../indexset/MongoIndexSetServiceTest.java | 80 ++++++++++++++----- .../IndexFieldTypeProfileServiceTest.java | 9 ++- ...ndexFieldTypeProfileUsagesServiceTest.java | 10 ++- .../indexset/MongoIndexSetServiceTest.json | 29 +++++++ 5 files changed, 111 insertions(+), 24 deletions(-) diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java index 9862222d3d9b..76fd625c296c 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/MongoIndexSetService.java @@ -201,7 +201,12 @@ public int delete(ObjectId id) { if (!isDeletable(id)) { return 0; } - int removedEntries = scopedEntityMongoUtils.deleteById(id) ? 1 : 0; + int removedEntries; + try { + removedEntries = scopedEntityMongoUtils.deleteById(id) ? 1 : 0; + } catch (IllegalArgumentException e) { + return 0; + } if (removedEntries > 0) { final IndexSetDeletedEvent deletedEvent = IndexSetDeletedEvent.create(id.toHexString()); clusterEventBus.post(deletedEvent); diff --git a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.java b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.java index e558132f6a87..609a113dfa1b 100644 --- a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.java +++ b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.java @@ -25,6 +25,8 @@ import org.graylog2.buffers.processors.fakestreams.FakeStream; import org.graylog2.cluster.ClusterConfigServiceImpl; import org.graylog2.database.MongoCollections; +import org.graylog2.database.entities.DefaultEntityScope; +import org.graylog2.database.entities.EntityScopeService; import org.graylog2.events.ClusterEventBus; import org.graylog2.indexer.indexset.events.IndexSetCreatedEvent; import org.graylog2.indexer.indexset.events.IndexSetDeletedEvent; @@ -53,10 +55,12 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import static org.assertj.core.api.Assertions.assertThat; import static org.graylog2.indexer.EventIndexTemplateProvider.EVENT_TEMPLATE_TYPE; +import static org.graylog2.indexer.indexset.SimpleIndexSetConfig.DEFAULT_FIELD_TYPE_REFRESH_INTERVAL; import static org.mockito.Mockito.when; public class MongoIndexSetServiceTest { @@ -78,19 +82,20 @@ public class MongoIndexSetServiceTest { private final NodeId nodeId = new SimpleNodeId("5ca1ab1e-0000-4000-a000-000000000000"); @Before - public void setUp() throws Exception { + public void setUp() { clusterEventBus = new ClusterEventBus(); clusterConfigService = new ClusterConfigServiceImpl(objectMapperProvider, mongodb.mongoConnection(), nodeId, new RestrictedChainingClassLoader( new ChainingClassLoader(getClass().getClassLoader()), SafeClasses.allGraylogInternal()), clusterEventBus); MongoCollections mongoCollections = new MongoCollections(objectMapperProvider, mongodb.mongoConnection()); - indexSetService = new MongoIndexSetService(mongoCollections, streamService, clusterConfigService, clusterEventBus); + final EntityScopeService entityScopeService = new EntityScopeService(Set.of(new DefaultEntityScope(), new SystemIndexSetScope())); + indexSetService = new MongoIndexSetService(mongoCollections, streamService, clusterConfigService, clusterEventBus, entityScopeService); } @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void getWithStringId() throws Exception { + public void getWithStringId() { final Optional indexSetConfig = indexSetService.get("57f3d721a43c2d59cb750001"); assertThat(indexSetConfig) .isPresent() @@ -119,7 +124,7 @@ public void getWithStringId() throws Exception { @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void getReturnsExistingIndexSetConfig() throws Exception { + public void getReturnsExistingIndexSetConfig() { final Optional indexSetConfig = indexSetService.get(new ObjectId("57f3d721a43c2d59cb750001")); assertThat(indexSetConfig) .isPresent() @@ -147,14 +152,14 @@ public void getReturnsExistingIndexSetConfig() throws Exception { } @Test - public void getReturnsAbsentOptionalIfIndexSetConfigDoesNotExist() throws Exception { + public void getReturnsAbsentOptionalIfIndexSetConfigDoesNotExist() { final Optional indexSetConfig = indexSetService.get(new ObjectId("57f3d3f0a43c2d595eb0a348")); assertThat(indexSetConfig).isEmpty(); } @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void getDefault() throws Exception { + public void getDefault() { clusterConfigService.write(DefaultIndexSetConfig.create("57f3d721a43c2d59cb750002")); final IndexSetConfig indexSetConfig = indexSetService.getDefault(); @@ -165,13 +170,13 @@ public void getDefault() throws Exception { @Test(expected = IllegalStateException.class) @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void getDefaultWithoutDefault() throws Exception { + public void getDefaultWithoutDefault() { indexSetService.getDefault(); } @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void findOne() throws Exception { + public void findOne() { final Optional config3 = indexSetService.findOne(DBQuery.is("title", "Test 2")); assertThat(config3).isPresent(); assertThat(config3.get().id()).isEqualTo("57f3d721a43c2d59cb750002"); @@ -182,12 +187,12 @@ public void findOne() throws Exception { @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void findAll() throws Exception { + public void findAll() { final List configs = indexSetService.findAll(); assertThat(configs) .isNotEmpty() - .hasSize(3) + .hasSize(4) .containsExactly( IndexSetConfig.create( "57f3d721a43c2d59cb750001", @@ -245,12 +250,35 @@ public void findAll() throws Exception { EVENT_TEMPLATE_TYPE, 1, false + ), + IndexSetConfig.create( + "57f3d721a43c2d59cb750004", + SystemIndexSetScope.NAME, + "Test 4", + "Index with system scope - not deletable", + true, null, + "test_4", + null, null, + 1, + 0, + MessageCountRotationStrategy.class.getCanonicalName(), + MessageCountRotationStrategyConfig.create(2500), + NoopRetentionStrategy.class.getCanonicalName(), + NoopRetentionStrategyConfig.create(25), + ZonedDateTime.of(2016, 10, 4, 18, 0, 0, 0, ZoneOffset.UTC), + "standard", + "test_4", + EVENT_TEMPLATE_TYPE, + 1, + false, + DEFAULT_FIELD_TYPE_REFRESH_INTERVAL, + null, null, null ) ); } @Test - public void save() throws Exception { + public void save() { final IndexSetCreatedSubscriber subscriber = new IndexSetCreatedSubscriber(); clusterEventBus.registerClusterEventSubscriber(subscriber); final IndexSetConfig indexSetConfig = IndexSetConfig.create( @@ -285,7 +313,7 @@ public void save() throws Exception { @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void deleteWithStringId() throws Exception { + public void deleteWithStringId() { final IndexSetDeletedSubscriber subscriber = new IndexSetDeletedSubscriber(); clusterEventBus.registerClusterEventSubscriber(subscriber); @@ -300,7 +328,7 @@ public void deleteWithStringId() throws Exception { @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void deleteRemovesExistingIndexSetConfig() throws Exception { + public void deleteRemovesExistingIndexSetConfig() { final IndexSetDeletedSubscriber subscriber = new IndexSetDeletedSubscriber(); clusterEventBus.registerClusterEventSubscriber(subscriber); @@ -315,22 +343,36 @@ public void deleteRemovesExistingIndexSetConfig() throws Exception { @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void deleteDoesNothingIfIndexSetConfigDoesNotExist() throws Exception { + public void deleteDoesNothingIfIndexSetConfigDoesNotExist() { final IndexSetDeletedSubscriber subscriber = new IndexSetDeletedSubscriber(); clusterEventBus.registerClusterEventSubscriber(subscriber); final int deletedEntries = indexSetService.delete("57f3d721a43c2d59cb750009"); - assertThat(deletedEntries).isEqualTo(0); + assertThat(deletedEntries).isZero(); assertThat(indexSetService.get("57f3d721a43c2d59cb750001")).isPresent(); assertThat(indexSetService.get("57f3d721a43c2d59cb750009")).isEmpty(); - assertThat(indexSetService.findAll()).hasSize(3); + assertThat(indexSetService.findAll()).hasSize(4); + + assertThat(subscriber.getEvents()).isEmpty(); + } + + + @Test + @MongoDBFixtures("MongoIndexSetServiceTest.json") + public void deleteThrowsIfInvalidScope() { + final IndexSetDeletedSubscriber subscriber = new IndexSetDeletedSubscriber(); + clusterEventBus.registerClusterEventSubscriber(subscriber); + + int deletedEntries = indexSetService.delete("57f3d721a43c2d59cb750004"); + assertThat(deletedEntries).isZero(); + assertThat(indexSetService.findAll()).hasSize(4); assertThat(subscriber.getEvents()).isEmpty(); } @Test @MongoDBFixtures("MongoIndexSetServiceTest.json") - public void deleteWithAssignedStreams() throws Exception { + public void deleteWithAssignedStreams() { final IndexSetDeletedSubscriber subscriber = new IndexSetDeletedSubscriber(); clusterEventBus.registerClusterEventSubscriber(subscriber); @@ -342,9 +384,9 @@ public void deleteWithAssignedStreams() throws Exception { when(streamService.loadAllWithIndexSet(streamId)).thenReturn(Collections.singletonList(stream1)); final int deletedEntries = indexSetService.delete(streamId); - assertThat(deletedEntries).isEqualTo(0); + assertThat(deletedEntries).isZero(); assertThat(indexSetService.get(streamId)).isPresent(); - assertThat(indexSetService.findAll()).hasSize(3); + assertThat(indexSetService.findAll()).hasSize(4); assertThat(subscriber.getEvents()).isEmpty(); } diff --git a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileServiceTest.java b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileServiceTest.java index d7617b6d9dc4..f4c707c180d3 100644 --- a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileServiceTest.java +++ b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileServiceTest.java @@ -21,6 +21,8 @@ import org.graylog2.bindings.providers.MongoJackObjectMapperProvider; import org.graylog2.database.MongoCollections; import org.graylog2.database.MongoConnection; +import org.graylog2.database.entities.DefaultEntityScope; +import org.graylog2.database.entities.EntityScopeService; import org.graylog2.events.ClusterEventBus; import org.graylog2.indexer.indexset.CustomFieldMapping; import org.graylog2.indexer.indexset.CustomFieldMappings; @@ -66,10 +68,12 @@ public void setUp() { final MongoConnection mongoConnection = mongodb.mongoConnection(); final MongoJackObjectMapperProvider objectMapperProvider = new MongoJackObjectMapperProvider(new ObjectMapperProvider().get()); MongoCollections mongoCollections = new MongoCollections(objectMapperProvider, mongodb.mongoConnection()); + final EntityScopeService entityScopeService = new EntityScopeService(Set.of(new DefaultEntityScope())); mongoIndexSetService = new MongoIndexSetService(mongoCollections, mock(StreamService.class), mock(ClusterConfigService.class), - mock(ClusterEventBus.class) + mock(ClusterEventBus.class), + entityScopeService ); indexFieldTypeProfileUsagesService = new IndexFieldTypeProfileUsagesService(mongoConnection); toTest = new IndexFieldTypeProfileService( @@ -267,8 +271,9 @@ private void verifyHasProfile(final String indexSetId, final String profileId) { private IndexSetConfig createIndexSetConfigForTest(final String id, final String description, final String profileId) { return IndexSetConfig.create( - id, "title", description, + id, null, + "title", description, true, true, "prefix_" + id, null, null, 1, 0, diff --git a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileUsagesServiceTest.java b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileUsagesServiceTest.java index 4e33cc06a9a3..b371add37dc9 100644 --- a/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileUsagesServiceTest.java +++ b/graylog2-server/src/test/java/org/graylog2/indexer/indexset/profile/IndexFieldTypeProfileUsagesServiceTest.java @@ -20,6 +20,8 @@ import org.graylog2.bindings.providers.MongoJackObjectMapperProvider; import org.graylog2.database.MongoCollections; import org.graylog2.database.MongoConnection; +import org.graylog2.database.entities.DefaultEntityScope; +import org.graylog2.database.entities.EntityScopeService; import org.graylog2.events.ClusterEventBus; import org.graylog2.indexer.indexset.CustomFieldMappings; import org.graylog2.indexer.indexset.IndexSetConfig; @@ -59,10 +61,13 @@ public void setUp() { final MongoConnection mongoConnection = mongodb.mongoConnection(); final MongoJackObjectMapperProvider objectMapperProvider = new MongoJackObjectMapperProvider(new ObjectMapperProvider().get()); MongoCollections mongoCollections = new MongoCollections(objectMapperProvider, mongodb.mongoConnection()); + final EntityScopeService entityScopeService = new EntityScopeService(Set.of(new DefaultEntityScope())); + final MongoIndexSetService mongoIndexSetService = new MongoIndexSetService(mongoCollections, mock(StreamService.class), mock(ClusterConfigService.class), - mock(ClusterEventBus.class) + mock(ClusterEventBus.class), + entityScopeService ); mongoIndexSetService.save(createIndexSetConfigForTest("000000000000000000000001", PROFILE1_ID)); mongoIndexSetService.save(createIndexSetConfigForTest("000000000000000000000011", PROFILE1_ID)); @@ -97,8 +102,9 @@ public void testReturnsProperUsagesForMultipleProfiles() { private IndexSetConfig createIndexSetConfigForTest(final String id, final String profileId) { return IndexSetConfig.create( - id, "title", "description", + id, null, + "title", "description", true, true, "prefix_" + id, null, null, 1, 0, diff --git a/graylog2-server/src/test/resources/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.json b/graylog2-server/src/test/resources/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.json index 6a9e426b0770..ac0d1e80fa17 100644 --- a/graylog2-server/src/test/resources/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.json +++ b/graylog2-server/src/test/resources/org/graylog2/indexer/indexset/MongoIndexSetServiceTest.json @@ -82,6 +82,35 @@ "index_template_type": "events", "index_optimization_max_num_segments": 1, "index_optimization_disabled": false + }, + { + "_id": { + "$oid": "57f3d721a43c2d59cb750004" + }, + "title": "Test 4", + "description": "Index with system scope - not deletable", + "index_prefix": "test_4", + "shards": 1, + "replicas": 0, + "rotation_strategy_class": "org.graylog2.indexer.rotation.strategies.MessageCountRotationStrategy", + "rotation_strategy": { + "type": "org.graylog2.indexer.rotation.strategies.MessageCountRotationStrategyConfig", + "max_docs_per_index": 2500 + }, + "retention_strategy_class": "org.graylog2.indexer.retention.strategies.NoopRetentionStrategy", + "retention_strategy": { + "type": "org.graylog2.indexer.retention.strategies.NoopRetentionStrategyConfig", + "max_number_of_indices": 25 + }, + "creation_date": { + "$date": "2016-10-04T18:00:00Z" + }, + "index_analyzer": "standard", + "index_template_name": "test_4", + "index_template_type": "events", + "index_optimization_max_num_segments": 1, + "index_optimization_disabled": false, + "_scope" : "GRAYLOG_SYSTEM_INDEX_SET_SCOPE" } ] } From 2f5f8a6e1e96650ad355aa25c1d0325e0d01e696 Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 13:42:15 +0100 Subject: [PATCH 4/8] check isRegular to determine scope --- .../java/org/graylog2/indexer/indexset/IndexSetConfig.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/IndexSetConfig.java b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/IndexSetConfig.java index d442c2f9557e..92444124b045 100644 --- a/graylog2-server/src/main/java/org/graylog2/indexer/indexset/IndexSetConfig.java +++ b/graylog2-server/src/main/java/org/graylog2/indexer/indexset/IndexSetConfig.java @@ -106,6 +106,10 @@ public static IndexSetConfig create(@Id @ObjectId @JsonProperty("_id") @Nullable fieldTypeRefreshIntervalValue = writableValue ? DEFAULT_FIELD_TYPE_REFRESH_INTERVAL : Duration.ZERO; } + if (scope == null) { + scope = Boolean.FALSE.equals(isRegular) ? SystemIndexSetScope.NAME : DefaultEntityScope.NAME; + } + return AutoValue_IndexSetConfig.builder() .id(id) .title(title) @@ -131,7 +135,7 @@ public static IndexSetConfig create(@Id @ObjectId @JsonProperty("_id") @Nullable .customFieldMappings(customFieldMappings == null ? new CustomFieldMappings() : customFieldMappings) .fieldTypeProfile(fieldTypeProfile) .dataTieringConfig(dataTiering) - .scope(scope == null ? DefaultEntityScope.NAME : scope) + .scope(scope) .build(); } From e08d499e4bf36080545cc148bed5f96b4b49dae1 Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 15:21:21 +0100 Subject: [PATCH 5/8] remove useless test --- .../system/indexer/IndexSetsResourceTest.java | 49 ++----------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/graylog2-server/src/test/java/org/graylog2/rest/resources/system/indexer/IndexSetsResourceTest.java b/graylog2-server/src/test/java/org/graylog2/rest/resources/system/indexer/IndexSetsResourceTest.java index c75b4990dd52..13a867242e3a 100644 --- a/graylog2-server/src/test/java/org/graylog2/rest/resources/system/indexer/IndexSetsResourceTest.java +++ b/graylog2-server/src/test/java/org/graylog2/rest/resources/system/indexer/IndexSetsResourceTest.java @@ -62,6 +62,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.lenient; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; @@ -288,48 +289,6 @@ public void saveDenied() { } } - @Test - public void update() { - final IndexSetConfig indexSetConfig = IndexSetConfig.create( - "id", - "new title", - "description", - true, false, - "prefix", - 1, - 0, - MessageCountRotationStrategy.class.getCanonicalName(), - MessageCountRotationStrategyConfig.create(1000), - NoopRetentionStrategy.class.getCanonicalName(), - NoopRetentionStrategyConfig.create(1), - ZonedDateTime.of(2016, 10, 10, 12, 0, 0, 0, ZoneOffset.UTC), - "standard", - "index-template", - null, - 1, - false - ); - final IndexSetConfig updatedIndexSetConfig = indexSetConfig.toBuilder() - .title("new title") - .build(); - - when(indexSetService.get("id")).thenReturn(Optional.of(indexSetConfig)); - when(indexSetService.save(indexSetConfig)).thenReturn(updatedIndexSetConfig); - - final IndexSetSummary summary = indexSetsResource.update("id", IndexSetUpdateRequest.fromIndexSetConfig(indexSetConfig)); - - verify(indexSetService, times(1)).get("id"); - verify(indexSetService, times(1)).save(indexSetConfig); - verify(indexSetService, times(1)).getDefault(); - verifyNoMoreInteractions(indexSetService); - - // The real update wouldn't replace the index template nameā€¦ - final IndexSetConfig actual = summary.toIndexSetConfig(false).toBuilder() - .indexTemplateName("index-template") - .build(); - assertThat(actual).isEqualTo(updatedIndexSetConfig); - } - @Test public void updateDenied() { notPermitted(); @@ -388,7 +347,7 @@ public void delete() throws Exception { final IndexSet indexSet = mock(IndexSet.class); final IndexSetConfig indexSetConfig = mock(IndexSetConfig.class); - when(indexSet.getConfig()).thenReturn(indexSetConfig); + lenient().when(indexSet.getConfig()).thenReturn(indexSetConfig); when(indexSetRegistry.get("id")).thenReturn(Optional.of(indexSet)); when(indexSetCleanupJobFactory.create(indexSet)).thenReturn(mock(IndexSetCleanupJob.class)); when(indexSetRegistry.getDefault()).thenReturn(null); @@ -498,7 +457,7 @@ public void setDefaultMakesIndexDefaultIfWritable() { false ); - when(indexSet.getConfig()).thenReturn(indexSetConfig); + lenient().when(indexSet.getConfig()).thenReturn(indexSetConfig); when(indexSetService.get(indexSetId)).thenReturn(Optional.of(indexSetConfig)); indexSetsResource.setDefault(indexSetId); @@ -671,7 +630,7 @@ private static class TestResource extends IndexSetsResource { protected Subject getSubject() { final Subject mockSubject = mock(Subject.class); when(mockSubject.isPermitted(anyString())).thenReturn(permitted.get()); - when(mockSubject.getPrincipal()).thenReturn("test-user"); + lenient().when(mockSubject.getPrincipal()).thenReturn("test-user"); return mockSubject; } } From 64fba311c5d1495bf50f211b09258789768de0ae Mon Sep 17 00:00:00 2001 From: patrickmann Date: Thu, 12 Dec 2024 16:39:34 +0100 Subject: [PATCH 6/8] force rebuild --- changelog/unreleased/pr-21174.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/unreleased/pr-21174.toml b/changelog/unreleased/pr-21174.toml index ddc86d2ecfa2..a681e6470c34 100644 --- a/changelog/unreleased/pr-21174.toml +++ b/changelog/unreleased/pr-21174.toml @@ -1,5 +1,5 @@ type = "c" -message = "Handle scoping for index sets: System index sets cannot be deleted." +message = "Handle scoping for index sets: System index sets cannot be deleted. " pulls = ["21174"] issues = ["Graylog2/graylog-plugin-enterprise#5904"] From 2b6985c9e599bc087d9a010d475f34b9005e61f2 Mon Sep 17 00:00:00 2001 From: Patrick Mann Date: Thu, 12 Dec 2024 16:45:16 +0100 Subject: [PATCH 7/8] force rebuild --- changelog/unreleased/pr-21174.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/unreleased/pr-21174.toml b/changelog/unreleased/pr-21174.toml index a681e6470c34..ddc86d2ecfa2 100644 --- a/changelog/unreleased/pr-21174.toml +++ b/changelog/unreleased/pr-21174.toml @@ -1,5 +1,5 @@ type = "c" -message = "Handle scoping for index sets: System index sets cannot be deleted. " +message = "Handle scoping for index sets: System index sets cannot be deleted." pulls = ["21174"] issues = ["Graylog2/graylog-plugin-enterprise#5904"] From 43c88e9ab06ba90734c1cf7af6ae114c0789eec2 Mon Sep 17 00:00:00 2001 From: patrickmann Date: Fri, 13 Dec 2024 09:58:45 +0100 Subject: [PATCH 8/8] force rebuild --- changelog/unreleased/pr-21174.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/unreleased/pr-21174.toml b/changelog/unreleased/pr-21174.toml index ddc86d2ecfa2..a681e6470c34 100644 --- a/changelog/unreleased/pr-21174.toml +++ b/changelog/unreleased/pr-21174.toml @@ -1,5 +1,5 @@ type = "c" -message = "Handle scoping for index sets: System index sets cannot be deleted." +message = "Handle scoping for index sets: System index sets cannot be deleted. " pulls = ["21174"] issues = ["Graylog2/graylog-plugin-enterprise#5904"]