Skip to content

Commit 6a85aab

Browse files
authored
Merge pull request #773 from metafacture/755-addMetafixExceptionLimit
Optionally specify limit for number of exceptions in Metafix.
2 parents 244e60d + 084cde3 commit 6a85aab

11 files changed

Lines changed: 127 additions & 17 deletions

File tree

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,4 @@ secring.gpg
5555
/metafix/src/test/resources/org/metafacture/metafix/integration/**/*.err
5656
/metafix/src/test/resources/org/metafacture/metafix/integration/**/*.out
5757
/metafix/src/test/resources/org/metafacture/metafix/integration/**/output-*
58-
!/metafix/src/test/resources/org/metafacture/metafix/integration/**/expected.err
58+
!/metafix/src/test/resources/org/metafacture/metafix/integration/**/expected.*

README.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,6 +1459,46 @@ Executes the functions if/unless the string matches the regular expression patte
14591459
14601460
[Java Code](https://github.com/metafacture/metafacture-core/blob/master/metafix/src/main/java/org/metafacture/metafix/conditional/StrMatch.java)
14611461
1462+
## Expert settings
1463+
1464+
Some settings are only applicable in very specific circumstances and may even be performance-sensitive. These settings cannot be configured via the usual Fix command or function options, but instead have to be set as [Java system properties](https://docs.oracle.com/javase/tutorial/essential/environment/sysprop.html).
1465+
1466+
When using the _Metafacture runner_ via `flux.sh` or `flux.bat`, you can set these system properties on the command line:
1467+
1468+
```bash
1469+
FLUX_JAVA_OPTIONS=-D<property>=<value> ./flux.sh ...
1470+
```
1471+
1472+
Or enable them permanently in the `config/java-options.conf` configuration file:
1473+
1474+
```bash
1475+
-D<property>=<value>
1476+
```
1477+
1478+
When using _Metafacture as a Java library_, you can set these system properties on the command line:
1479+
1480+
```bash
1481+
JAVA_OPTIONS=-D<property>=<value> java ...
1482+
```
1483+
1484+
Or configure them directly in your application code (before instantiating Metafix):
1485+
1486+
```java
1487+
System.setProperty("<property>", "<value>");
1488+
```
1489+
1490+
### Maximum entity count
1491+
1492+
The maximum number of Metafix entities being processed _per record_. Exceeding this limit leads to the remaining entities (as well as literals) being skipped for the current record; a log message is emitted at _DEBUG_ level for each excessive entity.
1493+
1494+
Accepts a non-negative integer: `org.metafacture.metafix.maxEntityCount=<int>` (Default: `-1`, i.e. no limit)
1495+
1496+
### Maximum exception count
1497+
1498+
The maximum number of Metafix exceptions being handled by the strictness level _per transformation_ (i.e. Metafix instance). Exceeding this limit leads to the configured strictness handling being skipped for the rest of the transformation; a log message is emitted at _INFO_ level for each unhandled exception (including the type of the current exception).
1499+
1500+
Accepts a non-negative integer: `org.metafacture.metafix.maxExceptionCount=<int>` (Default: `-1`, i.e. no limit)
1501+
14621502
## Xtext
14631503
14641504
The Metafix projects have been originally set up with [Xtext](https://www.eclipse.org/Xtext/) 2.17.0 and Eclipse for Java 2019-03, following [https://www.eclipse.org/Xtext/documentation/104_jvmdomainmodel.html](https://www.eclipse.org/Xtext/documentation/104_jvmdomainmodel.html).

metafacture-runner/src/main/dist/config/log4j2.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</Appenders>
1111
<Loggers>
1212
<!-- For developer logging change level to "DEBUG" -->
13-
<Root level="ERROR">
13+
<Root level="${sys:log4j2.level:-ERROR}">
1414
<AppenderRef ref="CONSOLE"/>
1515
</Root>
1616
<!-- For user logging with e.g. `log-object` change level to "DEBUG" -->

metafix/integrationTest.sh

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ todo_file=todo.txt
1212

1313
input_glob=input.*
1414
expected_glob=expected.*
15+
expected_output_extension=out
1516
expected_errors_extension=err
1617

1718
metafix_output_glob=output-metafix.*
@@ -207,6 +208,21 @@ function test_failed() {
207208
fi
208209
}
209210

211+
function test_expected_patterns() {
212+
local pattern
213+
214+
get_file "$1" "$4" "$5" || { log; return; }
215+
216+
while read -r pattern; do
217+
if ! grep -qE "$pattern" "$5"; then
218+
test_failed "$1" "$3" " (Pattern not found: $pattern)" FAILED "$6" "$7" "$8" "$9"
219+
return
220+
fi
221+
done <"$2"
222+
223+
test_passed "$1" "$3" "${10}"
224+
}
225+
210226
function run_tests() {
211227
local test matched=1\
212228
test_directory test_fix test_input test_expected test_todo\
@@ -248,7 +264,10 @@ function run_tests() {
248264
metafix_elapsed_time=$(elapsed_time "$metafix_start_time")
249265

250266
if [ "$metafix_exit_status" -eq 0 ]; then
251-
if get_file "$test" output "$test_directory"/$metafix_output_glob; then
267+
if [ "${test_expected##*.}" == "$expected_output_extension" ]; then
268+
test_expected_patterns "$test" "$test_expected" "$test_todo" output "$metafix_command_output"\
269+
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error" "$metafix_elapsed_time"
270+
elif get_file "$test" output "$test_directory"/$metafix_output_glob; then
252271
metafix_output=$current_file
253272
metafix_diff="$test_directory/metafix.diff"
254273

@@ -265,18 +284,8 @@ function run_tests() {
265284
command_info metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"
266285
fi
267286
elif [ "${test_expected##*.}" == "$expected_errors_extension" ]; then
268-
get_file "$test" error "$metafix_command_error" || { log; continue; }
269-
270-
while read -r pattern; do
271-
if ! grep -qE "$pattern" "$metafix_command_error"; then
272-
test_failed "$test" "$test_todo" " (Pattern not found: $pattern)" FAILED\
273-
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"
274-
275-
continue 2
276-
fi
277-
done <"$test_expected"
278-
279-
test_passed "$test" "$test_todo" "$metafix_elapsed_time"
287+
test_expected_patterns "$test" "$test_expected" "$test_todo" error "$metafix_command_error"\
288+
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error" "$metafix_elapsed_time"
280289
else
281290
test_failed "$test" "$test_todo" "$metafix_elapsed_time" ERROR\
282291
metafix "$metafix_exit_status" "$metafix_command_output" "$metafix_command_error"

metafix/src/main/java/org/metafacture/metafix/Metafix.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
@Out(StreamReceiver.class)
6767
@FluxCommand("fix")
6868
public class Metafix implements StreamPipe<StreamReceiver>, Maps {
69+
6970
public static final String ARRAY_MARKER = "[]";
7071
public static final String FIX_EXTENSION = ".fix";
7172
public static final String VAR_END = "]";
@@ -77,11 +78,14 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps {
7778
public static final Map<String, String> NO_VARS = Collections.emptyMap();
7879

7980
public static final int MAX_ENTITY_COUNT = Integer.getInteger("org.metafacture.metafix.maxEntityCount", -1);
81+
public static final int MAX_EXCEPTION_COUNT = Integer.getInteger("org.metafacture.metafix.maxExceptionCount", -1);
8082

8183
private static final MetafactureLogger LOG = new MetafactureLogger(Metafix.class);
8284

8385
private static final String ENTITIES_NOT_BALANCED = "Entity starts and ends are not balanced";
8486

87+
private static final String SKIP_EXCEPTION_PREFIX = "org.metafacture.";
88+
8589
private final Deque<Integer> entityCountStack = new LinkedList<>();
8690
private final FixRegistry registry = new FixRegistry();
8791
private final List<Closeable> resources = new ArrayList<>();
@@ -98,12 +102,13 @@ public class Metafix implements StreamPipe<StreamReceiver>, Maps {
98102
private Record currentRecord = new Record();
99103
private StreamReceiver outputStreamReceiver;
100104
private Strictness strictness = DEFAULT_STRICTNESS;
105+
private String entityMemberName = DEFAULT_ENTITY_MEMBER_NAME;
101106
private String fixFile;
102107
private String recordIdentifier;
103-
private String entityMemberName = DEFAULT_ENTITY_MEMBER_NAME;
104108
private boolean repeatedFieldsToEntities;
105109
private boolean strictnessHandlesProcessExceptions;
106110
private int entityCount;
111+
private int exceptionCount;
107112

108113
/**
109114
* Creates an instance of {@link Metafix}.
@@ -641,6 +646,43 @@ private boolean maxEntityCountExceeded() {
641646
return MAX_ENTITY_COUNT >= 0 && entityCount > MAX_ENTITY_COUNT;
642647
}
643648

649+
/**
650+
* Handles the exception based on the {@link #setStrictness selected strictness level},
651+
* provided that the {@link MAX_EXCEPTION_COUNT exception limit} has not been exceeded.
652+
*
653+
* @param exception the exception to be handled
654+
* @param record the current record
655+
*/
656+
public void handleException(final MetafactureException exception, final Record record) {
657+
++exceptionCount;
658+
659+
if (maxExceptionCountExceeded()) {
660+
LOG.info("Maximum number of exceptions exceeded: {}/{} (Current exception: {})",
661+
exceptionCount, MAX_EXCEPTION_COUNT, getExceptionCause(exception).getSimpleName());
662+
}
663+
else {
664+
strictness.handle(exception, record);
665+
}
666+
}
667+
668+
private boolean maxExceptionCountExceeded() {
669+
return MAX_EXCEPTION_COUNT >= 0 && exceptionCount > MAX_EXCEPTION_COUNT;
670+
}
671+
672+
private Class<?> getExceptionCause(final Throwable exception) {
673+
final Class<?> clazz = exception.getClass();
674+
675+
if (clazz.getPackageName().startsWith(SKIP_EXCEPTION_PREFIX)) {
676+
final Throwable cause = exception.getCause();
677+
678+
if (cause != null) {
679+
return getExceptionCause(cause);
680+
}
681+
}
682+
683+
return clazz;
684+
}
685+
644686
public enum Strictness {
645687

646688
/**
@@ -692,4 +734,5 @@ protected void log(final MetafactureException exception, final BiConsumer<String
692734
}
693735

694736
}
737+
695738
}

metafix/src/main/java/org/metafacture/metafix/RecordTransformer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ public void transform(final Record record) {
135135
final MetafactureException exception = tryRun(() -> consumer.accept(record));
136136

137137
if (exception != null) {
138-
metafix.getStrictness().handle(exception, record);
138+
metafix.handleException(exception, record);
139139
}
140140
});
141141
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
^[0-9T:.-]+ \[main\] WARN org\.metafacture\.metafix\.Metafix - Error while executing Fix expression \(at file:.*/metafix/src/test/resources/org/metafacture/metafix/integration/script/fromJson/toJson/maxExceptionCount/test\.fix, line 1\): upcase\("data"\)$
2+
^java\.lang\.IllegalStateException: Expected String, got Array$
3+
^[0-9T:.-]+ \[main\] INFO org\.metafacture\.metafix\.Metafix - Maximum number of exceptions exceeded: 2/1 \(Current exception: IllegalStateException\)$
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{"data":"foo"}
2+
{"data":"foo","data":"bar"}
3+
{"data":"foo","data":"baz"}
4+
{"data":"bar"}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-Dlog4j2.level=DEBUG
2+
-Dorg.metafacture.metafix.maxExceptionCount=1
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
upcase("data")

0 commit comments

Comments
 (0)