Skip to content

Commit cd3a32d

Browse files
Prevent load / publish failures when missing types are defined in hash keys (#679)
1 parent d32be3c commit cd3a32d

File tree

6 files changed

+568
-22
lines changed

6 files changed

+568
-22
lines changed

hollow/src/main/java/com/netflix/hollow/core/index/FieldPaths.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,8 @@ static FieldPath<FieldSegment> createFieldPath(
232232
/**
233233
* An exception contain structured information when a field path cannot be bound.
234234
*/
235-
static final class FieldPathException extends IllegalArgumentException {
236-
enum ErrorKind {
235+
public static final class FieldPathException extends IllegalArgumentException {
236+
public enum ErrorKind {
237237
NOT_BINDABLE,
238238
NOT_FOUND,
239239
NOT_FULL,
@@ -242,7 +242,7 @@ enum ErrorKind {
242242
;
243243
}
244244

245-
final ErrorKind error;
245+
public final ErrorKind error;
246246
final String rootType;
247247
final String[] segments;
248248

hollow/src/main/java/com/netflix/hollow/core/read/engine/map/HollowMapTypeReadState.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
*/
1717
package com.netflix.hollow.core.read.engine.map;
1818

19-
import static com.netflix.hollow.core.HollowConstants.ORDINAL_NONE;
20-
2119
import com.netflix.hollow.api.sampling.DisabledSamplingDirector;
2220
import com.netflix.hollow.api.sampling.HollowMapSampler;
2321
import com.netflix.hollow.api.sampling.HollowSampler;
2422
import com.netflix.hollow.api.sampling.HollowSamplingDirector;
23+
import com.netflix.hollow.core.index.FieldPaths;
2524
import com.netflix.hollow.core.index.key.HollowPrimaryKeyValueDeriver;
2625
import com.netflix.hollow.core.memory.MemoryMode;
2726
import com.netflix.hollow.core.memory.encoding.GapEncodedVariableLengthIntegerReader;
@@ -43,11 +42,17 @@
4342
import com.netflix.hollow.tools.checksum.HollowChecksum;
4443
import java.io.IOException;
4544
import java.util.BitSet;
45+
import java.util.logging.Level;
46+
import java.util.logging.Logger;
47+
48+
import static com.netflix.hollow.core.HollowConstants.ORDINAL_NONE;
49+
import static com.netflix.hollow.core.index.FieldPaths.FieldPathException.ErrorKind.NOT_BINDABLE;
4650

4751
/**
4852
* A {@link HollowTypeReadState} for MAP type records.
4953
*/
5054
public class HollowMapTypeReadState extends HollowTypeReadState implements HollowMapTypeDataAccess {
55+
private static final Logger LOG = Logger.getLogger(HollowMapTypeReadState.class.getName());
5156

5257
private final HollowMapSampler sampler;
5358

@@ -332,9 +337,19 @@ public HollowPrimaryKeyValueDeriver getKeyDeriver() {
332337
}
333338

334339
public void buildKeyDeriver() {
335-
if(getSchema().getHashKey() != null)
336-
this.keyDeriver = new HollowPrimaryKeyValueDeriver(getSchema().getHashKey(), getStateEngine());
337-
340+
if(getSchema().getHashKey() != null) {
341+
try {
342+
this.keyDeriver = new HollowPrimaryKeyValueDeriver(getSchema().getHashKey(), getStateEngine());
343+
} catch (FieldPaths.FieldPathException e) {
344+
if (e.error == NOT_BINDABLE) {
345+
LOG.log(Level.WARNING, "Failed to create a key value deriver for " + getSchema().getHashKey() +
346+
" because a field could not be bound to a type in the state");
347+
} else {
348+
throw e;
349+
}
350+
}
351+
}
352+
338353
for(int i=0; i<shards.length; i++)
339354
shards[i].setKeyDeriver(keyDeriver);
340355
}

hollow/src/main/java/com/netflix/hollow/core/read/engine/set/HollowSetTypeReadState.java

+20-5
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,11 @@
1616
*/
1717
package com.netflix.hollow.core.read.engine.set;
1818

19-
import static com.netflix.hollow.core.HollowConstants.ORDINAL_NONE;
20-
2119
import com.netflix.hollow.api.sampling.DisabledSamplingDirector;
2220
import com.netflix.hollow.api.sampling.HollowSampler;
2321
import com.netflix.hollow.api.sampling.HollowSamplingDirector;
2422
import com.netflix.hollow.api.sampling.HollowSetSampler;
23+
import com.netflix.hollow.core.index.FieldPaths;
2524
import com.netflix.hollow.core.index.key.HollowPrimaryKeyValueDeriver;
2625
import com.netflix.hollow.core.memory.MemoryMode;
2726
import com.netflix.hollow.core.memory.encoding.GapEncodedVariableLengthIntegerReader;
@@ -44,11 +43,17 @@
4443
import com.netflix.hollow.tools.checksum.HollowChecksum;
4544
import java.io.IOException;
4645
import java.util.BitSet;
46+
import java.util.logging.Level;
47+
import java.util.logging.Logger;
48+
49+
import static com.netflix.hollow.core.HollowConstants.ORDINAL_NONE;
50+
import static com.netflix.hollow.core.index.FieldPaths.FieldPathException.ErrorKind.NOT_BINDABLE;
4751

4852
/**
4953
* A {@link HollowTypeReadState} for OBJECT type records.
5054
*/
5155
public class HollowSetTypeReadState extends HollowCollectionTypeReadState implements HollowSetTypeDataAccess {
56+
private static final Logger LOG = Logger.getLogger(HollowSetTypeReadState.class.getName());
5257

5358
private final HollowSetSampler sampler;
5459

@@ -310,9 +315,19 @@ public HollowPrimaryKeyValueDeriver getKeyDeriver() {
310315
}
311316

312317
public void buildKeyDeriver() {
313-
if(getSchema().getHashKey() != null)
314-
this.keyDeriver = new HollowPrimaryKeyValueDeriver(getSchema().getHashKey(), getStateEngine());
315-
318+
if(getSchema().getHashKey() != null) {
319+
try {
320+
this.keyDeriver = new HollowPrimaryKeyValueDeriver(getSchema().getHashKey(), getStateEngine());
321+
} catch (FieldPaths.FieldPathException e) {
322+
if (e.error == NOT_BINDABLE) {
323+
LOG.log(Level.WARNING, "Failed to create a key value deriver for " + getSchema().getHashKey() +
324+
" because a field could not be bound to a type in the state");
325+
} else {
326+
throw e;
327+
}
328+
}
329+
}
330+
316331
for(int i=0;i<shards.length;i++)
317332
shards[i].setKeyDeriver(keyDeriver);
318333
}

hollow/src/main/java/com/netflix/hollow/core/write/HollowMapTypeWriteState.java

+31-5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package com.netflix.hollow.core.write;
1818

19+
import com.netflix.hollow.core.index.FieldPaths;
1920
import com.netflix.hollow.core.memory.ByteData;
2021
import com.netflix.hollow.core.memory.ByteDataArray;
2122
import com.netflix.hollow.core.memory.ThreadSafeBitSet;
@@ -26,8 +27,13 @@
2627
import com.netflix.hollow.core.schema.HollowMapSchema;
2728
import java.io.DataOutputStream;
2829
import java.io.IOException;
30+
import java.util.logging.Level;
31+
import java.util.logging.Logger;
32+
33+
import static com.netflix.hollow.core.index.FieldPaths.FieldPathException.ErrorKind.NOT_BINDABLE;
2934

3035
public class HollowMapTypeWriteState extends HollowTypeWriteState {
36+
private static final Logger LOG = Logger.getLogger(HollowMapTypeWriteState.class.getName());
3137

3238
/// statistics required for writing fixed length set data
3339
private int bitsPerMapPointer;
@@ -212,9 +218,19 @@ public void calculateSnapshot() {
212218

213219
HollowWriteStateEnginePrimaryKeyHasher primaryKeyHasher = null;
214220

215-
if(getSchema().getHashKey() != null)
216-
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
217-
221+
if(getSchema().getHashKey() != null) {
222+
try {
223+
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
224+
} catch (FieldPaths.FieldPathException e) {
225+
if (e.error == NOT_BINDABLE) {
226+
LOG.log(Level.WARNING, "Failed to create a key hasher for " + getSchema().getHashKey() +
227+
" because a field could not be bound to a type in the state");
228+
} else {
229+
throw e;
230+
}
231+
}
232+
}
233+
218234
for(int ordinal=0;ordinal<=maxOrdinal;ordinal++) {
219235
int shardNumber = ordinal & shardMask;
220236
int shardOrdinal = ordinal / numShards;
@@ -378,8 +394,18 @@ private void calculateDelta(ThreadSafeBitSet fromCyclePopulated, ThreadSafeBitSe
378394

379395
HollowWriteStateEnginePrimaryKeyHasher primaryKeyHasher = null;
380396

381-
if(getSchema().getHashKey() != null)
382-
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
397+
if(getSchema().getHashKey() != null) {
398+
try {
399+
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
400+
} catch (FieldPaths.FieldPathException e) {
401+
if (e.error == NOT_BINDABLE) {
402+
LOG.log(Level.WARNING, "Failed to create a key hasher for " + getSchema().getHashKey() +
403+
" because a field could not be bound to a type in the state");
404+
} else {
405+
throw e;
406+
}
407+
}
408+
}
383409

384410
for(int ordinal=0;ordinal<=maxOrdinal;ordinal++) {
385411
int shardNumber = ordinal & shardMask;

hollow/src/main/java/com/netflix/hollow/core/write/HollowSetTypeWriteState.java

+30-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package com.netflix.hollow.core.write;
1818

19+
import com.netflix.hollow.core.index.FieldPaths;
1920
import com.netflix.hollow.core.memory.ByteData;
2021
import com.netflix.hollow.core.memory.ByteDataArray;
2122
import com.netflix.hollow.core.memory.ThreadSafeBitSet;
@@ -26,8 +27,13 @@
2627
import com.netflix.hollow.core.schema.HollowSetSchema;
2728
import java.io.DataOutputStream;
2829
import java.io.IOException;
30+
import java.util.logging.Level;
31+
import java.util.logging.Logger;
32+
33+
import static com.netflix.hollow.core.index.FieldPaths.FieldPathException.ErrorKind.NOT_BINDABLE;
2934

3035
public class HollowSetTypeWriteState extends HollowTypeWriteState {
36+
private static final Logger LOG = Logger.getLogger(HollowSetTypeWriteState.class.getName());
3137

3238
/// statistics required for writing fixed length set data
3339
private int bitsPerSetPointer;
@@ -191,8 +197,18 @@ public void calculateSnapshot() {
191197

192198
HollowWriteStateEnginePrimaryKeyHasher primaryKeyHasher = null;
193199

194-
if(getSchema().getHashKey() != null)
195-
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
200+
if(getSchema().getHashKey() != null) {
201+
try {
202+
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
203+
} catch (FieldPaths.FieldPathException e) {
204+
if (e.error == NOT_BINDABLE) {
205+
LOG.log(Level.WARNING, "Failed to create a key hasher for " + getSchema().getHashKey() +
206+
" because a field could not be bound to a type in the state");
207+
} else {
208+
throw e;
209+
}
210+
}
211+
}
196212

197213
for(int ordinal=0;ordinal<=maxOrdinal;ordinal++) {
198214
int shardNumber = ordinal & shardMask;
@@ -350,8 +366,18 @@ public void calculateDelta(ThreadSafeBitSet fromCyclePopulated, ThreadSafeBitSet
350366

351367
HollowWriteStateEnginePrimaryKeyHasher primaryKeyHasher = null;
352368

353-
if(getSchema().getHashKey() != null)
354-
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
369+
if(getSchema().getHashKey() != null) {
370+
try {
371+
primaryKeyHasher = new HollowWriteStateEnginePrimaryKeyHasher(getSchema().getHashKey(), getStateEngine());
372+
} catch (FieldPaths.FieldPathException e) {
373+
if (e.error == NOT_BINDABLE) {
374+
LOG.log(Level.WARNING, "Failed to create a key hasher for " + getSchema().getHashKey() +
375+
" because a field could not be bound to a type in the state");
376+
} else {
377+
throw e;
378+
}
379+
}
380+
}
355381

356382
for(int ordinal=0;ordinal<=maxOrdinal;ordinal++) {
357383
int shardNumber = ordinal & shardMask;

0 commit comments

Comments
 (0)