Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 976ba41

Browse files
sarthakaggarwal97andrross
authored andcommittedJul 26, 2024··
Validating QAT Hardware Support before QAT Codecs are available (#169)
* validating QAT hardware support before making codecs available Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com> * Store result of `isQatAvailable` in static field Signed-off-by: Andrew Ross <andrross@amazon.com> --------- Signed-off-by: Sarthak Aggarwal <sarthagg@amazon.com> Signed-off-by: Andrew Ross <andrross@amazon.com> Co-authored-by: Andrew Ross <andrross@amazon.com> (cherry picked from commit 3ab314b)
1 parent edb801d commit 976ba41

File tree

7 files changed

+119
-18
lines changed

7 files changed

+119
-18
lines changed
 

‎src/integrationTest/java/org/opensearch/index/codec/rest/CreateIndexWithCodecIT.java

+45
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717
import org.apache.http.conn.ssl.TrustAllStrategy;
1818
import org.apache.http.impl.client.BasicCredentialsProvider;
1919

20+
import org.opensearch.client.ResponseException;
2021
import org.opensearch.client.RestClient;
2122
import org.opensearch.client.RestClientBuilder;
2223
import org.opensearch.cluster.metadata.IndexMetadata;
2324
import org.opensearch.common.settings.Settings;
2425
import org.opensearch.core.common.Strings;
26+
import org.opensearch.index.codec.customcodecs.Lucene99QatCodec;
2527
import org.opensearch.index.codec.customcodecs.QatZipperFactory;
2628
import org.opensearch.test.rest.OpenSearchRestTestCase;
2729

@@ -64,6 +66,49 @@ public void testCreateIndexWithZstdCodec() throws IOException {
6466
}
6567
}
6668

69+
public void testCreateIndexWithQatCodecWithQatHardwareUnavailable() throws IOException {
70+
71+
assumeThat("Qat library is not available", QatZipperFactory.isQatAvailable(), is(false));
72+
final String index = "custom-codecs-test-index";
73+
74+
// creating index
75+
final ResponseException e = expectThrows(
76+
ResponseException.class,
77+
() -> createIndex(
78+
index,
79+
Settings.builder()
80+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
81+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
82+
.put("index.codec", randomFrom(QAT_DEFLATE_CODEC, QAT_LZ4_CODEC))
83+
.put("index.codec.compression_level", randomIntBetween(1, 6))
84+
.build()
85+
)
86+
);
87+
assertTrue(e.getResponse().toString().contains("400 Bad Request"));
88+
}
89+
90+
public void testCreateIndexWithQatSPICodecWithQatHardwareUnavailable() throws IOException {
91+
92+
assumeThat("Qat library is not available", QatZipperFactory.isQatAvailable(), is(false));
93+
final String index = "custom-codecs-test-index";
94+
95+
// creating index
96+
final ResponseException e = expectThrows(
97+
ResponseException.class,
98+
() -> createIndex(
99+
index,
100+
Settings.builder()
101+
.put(IndexMetadata.SETTING_NUMBER_OF_SHARDS, 1)
102+
.put(IndexMetadata.SETTING_NUMBER_OF_REPLICAS, 0)
103+
.put("index.codec", randomFrom(Lucene99QatCodec.Mode.QAT_LZ4.getCodec(), Lucene99QatCodec.Mode.QAT_DEFLATE.getCodec()))
104+
.put("index.codec.compression_level", randomIntBetween(1, 6))
105+
.build()
106+
)
107+
);
108+
assertTrue(e.getResponse().toString().contains("400 Bad Request"));
109+
110+
}
111+
67112
public void testCreateIndexWithQatCodec() throws IOException {
68113
assumeThat("Qat library is available", QatZipperFactory.isQatAvailable(), is(true));
69114

‎src/main/java/org/opensearch/index/codec/customcodecs/CustomCodecPlugin.java

+7
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ public Optional<CodecServiceFactory> getCustomCodecServiceFactory(final IndexSet
4848
|| codecName.equals(CustomCodecService.QAT_LZ4_CODEC)
4949
|| codecName.equals(CustomCodecService.QAT_DEFLATE_CODEC)) {
5050
return Optional.of(new CustomCodecServiceFactory());
51+
} else {
52+
if (!QatZipperFactory.isQatAvailable()
53+
&& (codecName.equals(Lucene99QatCodec.Mode.QAT_LZ4.getCodec())
54+
|| codecName.equals(Lucene99QatCodec.Mode.QAT_DEFLATE.getCodec()))) {
55+
throw new IllegalArgumentException("QAT codecs are not supported. Please create indices with a different codec.");
56+
}
57+
5158
}
5259
return Optional.empty();
5360
}

‎src/main/java/org/opensearch/index/codec/customcodecs/CustomCodecService.java

+16-12
Original file line numberDiff line numberDiff line change
@@ -51,21 +51,25 @@ public CustomCodecService(MapperService mapperService, IndexSettings indexSettin
5151
if (mapperService == null) {
5252
codecs.put(ZSTD_CODEC, new Zstd99Codec(compressionLevel));
5353
codecs.put(ZSTD_NO_DICT_CODEC, new ZstdNoDict99Codec(compressionLevel));
54-
codecs.put(QAT_LZ4_CODEC, new QatLz499Codec(compressionLevel, () -> {
55-
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
56-
}));
57-
codecs.put(QAT_DEFLATE_CODEC, new QatDeflate99Codec(compressionLevel, () -> {
58-
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
59-
}));
54+
if (QatZipperFactory.isQatAvailable()) {
55+
codecs.put(QAT_LZ4_CODEC, new QatLz499Codec(compressionLevel, () -> {
56+
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
57+
}));
58+
codecs.put(QAT_DEFLATE_CODEC, new QatDeflate99Codec(compressionLevel, () -> {
59+
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
60+
}));
61+
}
6062
} else {
6163
codecs.put(ZSTD_CODEC, new Zstd99Codec(mapperService, logger, compressionLevel));
6264
codecs.put(ZSTD_NO_DICT_CODEC, new ZstdNoDict99Codec(mapperService, logger, compressionLevel));
63-
codecs.put(QAT_LZ4_CODEC, new QatLz499Codec(mapperService, logger, compressionLevel, () -> {
64-
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
65-
}));
66-
codecs.put(QAT_DEFLATE_CODEC, new QatDeflate99Codec(mapperService, logger, compressionLevel, () -> {
67-
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
68-
}));
65+
if (QatZipperFactory.isQatAvailable()) {
66+
codecs.put(QAT_LZ4_CODEC, new QatLz499Codec(mapperService, logger, compressionLevel, () -> {
67+
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
68+
}));
69+
codecs.put(QAT_DEFLATE_CODEC, new QatDeflate99Codec(mapperService, logger, compressionLevel, () -> {
70+
return indexSettings.getValue(Lucene99QatCodec.INDEX_CODEC_QAT_MODE_SETTING);
71+
}));
72+
}
6973
}
7074
this.codecs = codecs.immutableMap();
7175
}

‎src/main/java/org/opensearch/index/codec/customcodecs/QatDeflate99Codec.java

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public boolean supports(Setting<?> setting) {
8686

8787
@Override
8888
public Set<String> aliases() {
89+
if (!QatZipperFactory.isQatAvailable()) {
90+
return Set.of();
91+
}
8992
return Mode.QAT_DEFLATE.getAliases();
9093
}
9194
}

‎src/main/java/org/opensearch/index/codec/customcodecs/QatLz499Codec.java

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public boolean supports(Setting<?> setting) {
8686

8787
@Override
8888
public Set<String> aliases() {
89+
if (!QatZipperFactory.isQatAvailable()) {
90+
return Set.of();
91+
}
8992
return Mode.QAT_LZ4.getAliases();
9093
}
9194
}

‎src/main/java/org/opensearch/index/codec/customcodecs/QatZipperFactory.java

+19-6
Original file line numberDiff line numberDiff line change
@@ -172,12 +172,25 @@ public static QatZipper createInstance(Algorithm algorithm, int level, Mode mode
172172
* @return true if QAT hardware is available, false otherwise.
173173
*/
174174
public static boolean isQatAvailable() {
175-
try {
176-
QatZipper qzip = QatZipperFactory.createInstance();
177-
qzip.end();
178-
return true;
179-
} catch (UnsatisfiedLinkError | ExceptionInInitializerError | NoClassDefFoundError e) {
180-
return false;
175+
return QatAvailableHolder.IS_QAT_AVAILABLE;
176+
}
177+
178+
/**
179+
* Nested class to defer static initialization until {@link #isQatAvailable()} is invoked
180+
*/
181+
private static class QatAvailableHolder {
182+
static final boolean IS_QAT_AVAILABLE;
183+
184+
static {
185+
boolean isQatAvailable;
186+
try {
187+
final QatZipper qzip = QatZipperFactory.createInstance();
188+
qzip.end();
189+
isQatAvailable = true;
190+
} catch (UnsatisfiedLinkError | ExceptionInInitializerError | NoClassDefFoundError e) {
191+
isQatAvailable = false;
192+
}
193+
IS_QAT_AVAILABLE = isQatAvailable;
181194
}
182195
}
183196
}

‎src/test/java/org/opensearch/index/codec/customcodecs/CustomCodecTests.java

+26
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@
6565
import java.util.Collections;
6666
import java.util.Optional;
6767

68+
import static org.opensearch.index.codec.customcodecs.CustomCodecService.QAT_DEFLATE_CODEC;
69+
import static org.opensearch.index.codec.customcodecs.CustomCodecService.QAT_LZ4_CODEC;
6870
import static org.opensearch.index.codec.customcodecs.CustomCodecService.ZSTD_CODEC;
6971
import static org.opensearch.index.codec.customcodecs.CustomCodecService.ZSTD_NO_DICT_CODEC;
7072
import static org.opensearch.index.engine.EngineConfig.INDEX_CODEC_COMPRESSION_LEVEL_SETTING;
@@ -176,6 +178,30 @@ public void testZstdNoDictMapperServiceNull() throws Exception {
176178
assertEquals(Lucene99CustomCodec.DEFAULT_COMPRESSION_LEVEL, storedFieldsFormat.getCompressionLevel());
177179
}
178180

181+
public void testQatCodecsNotAvailable() throws IOException {
182+
if (!QatZipperFactory.isQatAvailable()) {
183+
assertThrows(IllegalArgumentException.class, () -> createCodecService(false).codec("qat_lz4"));
184+
assertThrows(IllegalArgumentException.class, () -> createCodecService(false).codec("qat_deflate"));
185+
186+
QatLz499Codec qatLz499Codec = new QatLz499Codec();
187+
assertTrue(qatLz499Codec.aliases().isEmpty());
188+
189+
QatDeflate99Codec qatDeflate99Codec = new QatDeflate99Codec();
190+
assertTrue(qatDeflate99Codec.aliases().isEmpty());
191+
}
192+
}
193+
194+
public void testCodecServiceFactoryQatUnavailable() throws IOException {
195+
if (!QatZipperFactory.isQatAvailable()) {
196+
Settings nodeSettings = Settings.builder()
197+
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir())
198+
.put("index.codec", randomFrom(QAT_DEFLATE_CODEC, QAT_LZ4_CODEC))
199+
.build();
200+
IndexSettings indexSettings = IndexSettingsModule.newIndexSettings("_na", nodeSettings);
201+
assertThrows(IllegalArgumentException.class, () -> plugin.getCustomCodecServiceFactory(indexSettings));
202+
}
203+
}
204+
179205
// write some docs with it, inspect .si to see this was the used compression
180206
private void assertStoredFieldsCompressionEquals(Lucene99Codec.Mode expected, Codec actual) throws Exception {
181207
SegmentReader sr = getSegmentReader(actual);

0 commit comments

Comments
 (0)
Please sign in to comment.