use of org.opensearch.env.NodeEnvironment in project OpenSearch by opensearch-project.
the class PersistedClusterStateServiceTests method testFailsIfIndexMetadataIsDuplicated.
public void testFailsIfIndexMetadataIsDuplicated() throws IOException {
// if someone attempted surgery on the metadata index by hand, e.g. deleting broken segments, then maybe some index metadata
// is duplicated
final Path[] dataPaths1 = createDataPaths();
final Path[] dataPaths2 = createDataPaths();
final Path[] combinedPaths = Stream.concat(Arrays.stream(dataPaths1), Arrays.stream(dataPaths2)).toArray(Path[]::new);
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(combinedPaths)) {
final String indexUUID = UUIDs.randomBase64UUID(random());
final String indexName = randomAlphaOfLength(10);
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(newPersistedClusterStateService(nodeEnvironment));
writeState(writer, 0L, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).version(1L).coordinationMetadata(CoordinationMetadata.builder(clusterState.coordinationMetadata()).term(1L).build()).put(IndexMetadata.builder(indexName).version(1L).settings(Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0).put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.CURRENT).put(IndexMetadata.SETTING_INDEX_UUID, indexUUID)))).incrementVersion().build(), clusterState);
}
final Path brokenPath = randomFrom(nodeEnvironment.nodeDataPaths());
final Path dupPath = randomValueOtherThan(brokenPath, () -> randomFrom(nodeEnvironment.nodeDataPaths()));
try (Directory directory = new NIOFSDirectory(brokenPath.resolve(PersistedClusterStateService.METADATA_DIRECTORY_NAME));
Directory dupDirectory = new NIOFSDirectory(dupPath.resolve(PersistedClusterStateService.METADATA_DIRECTORY_NAME))) {
try (IndexWriter indexWriter = new IndexWriter(directory, new IndexWriterConfig())) {
// do not duplicate global metadata
indexWriter.deleteDocuments(new Term("type", "global"));
indexWriter.addIndexes(dupDirectory);
indexWriter.commit();
}
}
final String message = expectThrows(IllegalStateException.class, () -> newPersistedClusterStateService(nodeEnvironment).loadBestOnDiskState()).getMessage();
assertThat(message, allOf(containsString("duplicate metadata found"), containsString(brokenPath.toString()), containsString(indexName), containsString(indexUUID)));
}
}
use of org.opensearch.env.NodeEnvironment in project OpenSearch by opensearch-project.
the class PersistedClusterStateServiceTests method testPersistsAndReloadsIndexMetadataIffVersionOrTermChanges.
public void testPersistsAndReloadsIndexMetadataIffVersionOrTermChanges() throws IOException {
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(createDataPaths())) {
final PersistedClusterStateService persistedClusterStateService = newPersistedClusterStateService(nodeEnvironment);
final long globalVersion = randomLongBetween(1L, Long.MAX_VALUE);
final String indexUUID = UUIDs.randomBase64UUID(random());
final long indexMetadataVersion = randomLongBetween(1L, Long.MAX_VALUE);
final long oldTerm = randomLongBetween(1L, Long.MAX_VALUE - 1);
final long newTerm = randomLongBetween(oldTerm + 1, Long.MAX_VALUE);
try (Writer writer = persistedClusterStateService.createWriter()) {
ClusterState clusterState = loadPersistedClusterState(persistedClusterStateService);
writeState(writer, 0L, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).version(globalVersion).coordinationMetadata(CoordinationMetadata.builder(clusterState.coordinationMetadata()).term(oldTerm).build()).put(IndexMetadata.builder("test").version(// -1 because it's incremented in .put()
indexMetadataVersion - 1).settings(Settings.builder().put(IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING.getKey(), 1).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 0).put(IndexMetadata.SETTING_INDEX_VERSION_CREATED.getKey(), Version.CURRENT).put(IndexMetadata.SETTING_INDEX_UUID, indexUUID)))).incrementVersion().build(), clusterState);
clusterState = loadPersistedClusterState(persistedClusterStateService);
IndexMetadata indexMetadata = clusterState.metadata().index("test");
assertThat(indexMetadata.getIndexUUID(), equalTo(indexUUID));
assertThat(indexMetadata.getVersion(), equalTo(indexMetadataVersion));
assertThat(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.get(indexMetadata.getSettings()), equalTo(0));
// ensure we do not wastefully persist the same index metadata version by making a bad update with the same version
writer.writeIncrementalStateAndCommit(0L, clusterState, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).put(IndexMetadata.builder(indexMetadata).settings(Settings.builder().put(indexMetadata.getSettings()).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 1)).build(), false)).incrementVersion().build());
clusterState = loadPersistedClusterState(persistedClusterStateService);
indexMetadata = clusterState.metadata().index("test");
assertThat(indexMetadata.getIndexUUID(), equalTo(indexUUID));
assertThat(indexMetadata.getVersion(), equalTo(indexMetadataVersion));
assertThat(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.get(indexMetadata.getSettings()), equalTo(0));
// ensure that we do persist the same index metadata version by making an update with a higher version
writeState(writer, 0L, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).put(IndexMetadata.builder(indexMetadata).settings(Settings.builder().put(indexMetadata.getSettings()).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 2)).build(), true)).incrementVersion().build(), clusterState);
clusterState = loadPersistedClusterState(persistedClusterStateService);
indexMetadata = clusterState.metadata().index("test");
assertThat(indexMetadata.getVersion(), equalTo(indexMetadataVersion + 1));
assertThat(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.get(indexMetadata.getSettings()), equalTo(2));
// ensure that we also persist the index metadata when the term changes
writeState(writer, 0L, ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).coordinationMetadata(CoordinationMetadata.builder(clusterState.coordinationMetadata()).term(newTerm).build()).put(IndexMetadata.builder(indexMetadata).settings(Settings.builder().put(indexMetadata.getSettings()).put(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.getKey(), 3)).build(), false)).incrementVersion().build(), clusterState);
}
final ClusterState clusterState = loadPersistedClusterState(persistedClusterStateService);
final IndexMetadata indexMetadata = clusterState.metadata().index("test");
assertThat(indexMetadata.getIndexUUID(), equalTo(indexUUID));
assertThat(indexMetadata.getVersion(), equalTo(indexMetadataVersion + 1));
assertThat(IndexMetadata.INDEX_NUMBER_OF_REPLICAS_SETTING.get(indexMetadata.getSettings()), equalTo(3));
}
}
use of org.opensearch.env.NodeEnvironment in project OpenSearch by opensearch-project.
the class PersistedClusterStateServiceTests method testFailsOnMismatchedNodeIds.
public void testFailsOnMismatchedNodeIds() throws IOException {
final Path[] dataPaths1 = createDataPaths();
final Path[] dataPaths2 = createDataPaths();
final String[] nodeIds = new String[2];
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(dataPaths1)) {
nodeIds[0] = nodeEnvironment.nodeId();
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(newPersistedClusterStateService(nodeEnvironment));
writer.writeFullStateAndCommit(0L, ClusterState.builder(clusterState).version(randomLongBetween(1L, Long.MAX_VALUE)).build());
}
}
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(dataPaths2)) {
nodeIds[1] = nodeEnvironment.nodeId();
try (Writer writer = newPersistedClusterStateService(nodeEnvironment).createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(newPersistedClusterStateService(nodeEnvironment));
writer.writeFullStateAndCommit(0L, ClusterState.builder(clusterState).version(randomLongBetween(1L, Long.MAX_VALUE)).build());
}
}
NodeMetadata.FORMAT.cleanupOldFiles(Long.MAX_VALUE, dataPaths2);
final Path[] combinedPaths = Stream.concat(Arrays.stream(dataPaths1), Arrays.stream(dataPaths2)).toArray(Path[]::new);
final String failure = expectThrows(IllegalStateException.class, () -> newNodeEnvironment(combinedPaths)).getMessage();
assertThat(failure, allOf(containsString("unexpected node ID in metadata"), containsString(nodeIds[0]), containsString(nodeIds[1])));
assertTrue("[" + failure + "] should match " + Arrays.toString(dataPaths2), Arrays.stream(dataPaths2).anyMatch(p -> failure.contains(p.toString())));
// verify that loadBestOnDiskState has same check
final String message = expectThrows(IllegalStateException.class, () -> new PersistedClusterStateService(Stream.of(combinedPaths).map(path -> NodeEnvironment.resolveNodePath(path, 0)).toArray(Path[]::new), nodeIds[0], xContentRegistry(), BigArrays.NON_RECYCLING_INSTANCE, new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L).loadBestOnDiskState()).getMessage();
assertThat(message, allOf(containsString("unexpected node ID in metadata"), containsString(nodeIds[0]), containsString(nodeIds[1])));
assertTrue("[" + message + "] should match " + Arrays.toString(dataPaths2), Arrays.stream(dataPaths2).anyMatch(p -> message.contains(p.toString())));
}
use of org.opensearch.env.NodeEnvironment in project OpenSearch by opensearch-project.
the class PersistedClusterStateServiceTests method testClosesWriterOnFatalError.
public void testClosesWriterOnFatalError() throws IOException {
final AtomicBoolean throwException = new AtomicBoolean();
try (NodeEnvironment nodeEnvironment = newNodeEnvironment(createDataPaths())) {
final PersistedClusterStateService persistedClusterStateService = new PersistedClusterStateService(nodeEnvironment, xContentRegistry(), getBigArrays(), new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L) {
@Override
Directory createDirectory(Path path) throws IOException {
return new FilterDirectory(super.createDirectory(path)) {
@Override
public void sync(Collection<String> names) {
throw new OutOfMemoryError("simulated");
}
};
}
};
try (Writer writer = persistedClusterStateService.createWriter()) {
final ClusterState clusterState = loadPersistedClusterState(persistedClusterStateService);
final long newTerm = randomNonNegativeLong();
final ClusterState newState = ClusterState.builder(clusterState).metadata(Metadata.builder(clusterState.metadata()).clusterUUID(UUIDs.randomBase64UUID(random())).clusterUUIDCommitted(true).version(randomLongBetween(1L, Long.MAX_VALUE))).incrementVersion().build();
throwException.set(true);
assertThat(expectThrows(OutOfMemoryError.class, () -> {
if (randomBoolean()) {
writeState(writer, newTerm, newState, clusterState);
} else {
writer.commit(newTerm, newState.version());
}
}).getMessage(), containsString("simulated"));
assertFalse(writer.isOpen());
}
// check if we can open writer again
try (Writer ignored = persistedClusterStateService.createWriter()) {
}
}
}
use of org.opensearch.env.NodeEnvironment in project OpenSearch by opensearch-project.
the class GatewayMetaStatePersistedStateTests method testStatePersistenceWithIOIssues.
public void testStatePersistenceWithIOIssues() throws IOException {
final AtomicReference<Double> ioExceptionRate = new AtomicReference<>(0.01d);
final List<MockDirectoryWrapper> list = new ArrayList<>();
final PersistedClusterStateService persistedClusterStateService = new PersistedClusterStateService(nodeEnvironment, xContentRegistry(), getBigArrays(), new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L) {
@Override
Directory createDirectory(Path path) {
final MockDirectoryWrapper wrapper = newMockFSDirectory(path);
wrapper.setAllowRandomFileNotFoundException(randomBoolean());
wrapper.setRandomIOExceptionRate(ioExceptionRate.get());
wrapper.setRandomIOExceptionRateOnOpen(ioExceptionRate.get());
list.add(wrapper);
return wrapper;
}
};
ClusterState state = createClusterState(randomNonNegativeLong(), Metadata.builder().clusterUUID(randomAlphaOfLength(10)).build());
long currentTerm = 42L;
try (GatewayMetaState.LucenePersistedState persistedState = new GatewayMetaState.LucenePersistedState(persistedClusterStateService, currentTerm, state)) {
try {
if (randomBoolean()) {
final ClusterState newState = createClusterState(randomNonNegativeLong(), Metadata.builder().clusterUUID(randomAlphaOfLength(10)).build());
persistedState.setLastAcceptedState(newState);
state = newState;
} else {
final long newTerm = currentTerm + 1;
persistedState.setCurrentTerm(newTerm);
currentTerm = newTerm;
}
} catch (IOError | Exception e) {
assertNotNull(ExceptionsHelper.unwrap(e, IOException.class));
}
ioExceptionRate.set(0.0d);
for (MockDirectoryWrapper wrapper : list) {
wrapper.setRandomIOExceptionRate(ioExceptionRate.get());
wrapper.setRandomIOExceptionRateOnOpen(ioExceptionRate.get());
}
for (int i = 0; i < randomIntBetween(1, 5); i++) {
if (randomBoolean()) {
final long version = randomNonNegativeLong();
final String indexName = randomAlphaOfLength(10);
final IndexMetadata indexMetadata = createIndexMetadata(indexName, randomIntBetween(1, 5), randomNonNegativeLong());
final Metadata metadata = Metadata.builder().persistentSettings(Settings.builder().put(randomAlphaOfLength(10), randomAlphaOfLength(10)).build()).coordinationMetadata(createCoordinationMetadata(1L)).put(indexMetadata, false).build();
state = createClusterState(version, metadata);
persistedState.setLastAcceptedState(state);
} else {
currentTerm += 1;
persistedState.setCurrentTerm(currentTerm);
}
}
assertEquals(state, persistedState.getLastAcceptedState());
assertEquals(currentTerm, persistedState.getCurrentTerm());
} catch (IOError | Exception e) {
if (ioExceptionRate.get() == 0.0d) {
throw e;
}
assertNotNull(ExceptionsHelper.unwrap(e, IOException.class));
return;
}
nodeEnvironment.close();
// verify that the freshest state was rewritten to each data path
for (Path path : nodeEnvironment.nodeDataPaths()) {
Settings settings = Settings.builder().put(Environment.PATH_HOME_SETTING.getKey(), createTempDir().toAbsolutePath()).put(Environment.PATH_DATA_SETTING.getKey(), path.getParent().getParent().toString()).build();
try (NodeEnvironment nodeEnvironment = new NodeEnvironment(settings, TestEnvironment.newEnvironment(settings))) {
final PersistedClusterStateService newPersistedClusterStateService = new PersistedClusterStateService(nodeEnvironment, xContentRegistry(), getBigArrays(), new ClusterSettings(settings, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS), () -> 0L);
final PersistedClusterStateService.OnDiskState onDiskState = newPersistedClusterStateService.loadBestOnDiskState();
assertFalse(onDiskState.empty());
assertThat(onDiskState.currentTerm, equalTo(currentTerm));
assertClusterStateEqual(state, ClusterState.builder(ClusterName.DEFAULT).version(onDiskState.lastAcceptedVersion).metadata(onDiskState.metadata).build());
}
}
}
Aggregations