Python/Jython dictionaries also support a get() method that allows you
to provide a value to use if the key is not in the dictionary.
The question is what do you want to have happen if your result
dictionary doesn't contain the value? Do you want it to continue on, or
do you want it to fail?
if result.get('application', '') in valid_application and
result.get('environment', '') in valid_environment ...
If you want it to continue on if they are missing, then add an empty
string to each of the sets you are comparing. Also, if an empty string
is a possible input and you want to have the missing value be different,
you can specify a different default as the second argument to the get()
method.
The KeyError is thrown whenever you try to reference a key that isn't in
the dictionary. This page[1] might provide you some more helpful details.
- Scott
[1] https://wiki.python.org/moin/KeyError
James McMahon <mailto:[email protected]>
Wednesday, July 12, 2017 4:43 AM
Thank you very much, Matt and Andy. I will explore these suggested
improvements to my logic this evening and post the results. Cheers, Jim
Matt Burgess <mailto:[email protected]>
Tuesday, July 11, 2017 8:25 PM
Jim,
You can check first if the key is in the results dictionary and then
if the value is in the valid values dictionary:
...
and 'environment' in result and result['environment'] in valid_environment
...
if a missing value is "valid", then you can use "or" instead of "and"
and put the clause in parens:
...
and ('environment' in result or result['environment'] in
valid_environment)
...
If I misunderstood what you were asking please let me know and I'll
try again :)
Regards,
Matt
James McMahon <mailto:[email protected]>
Tuesday, July 11, 2017 8:12 PM
Good evening. I am in a Jython 2.7.0 environment, using NiFi 1.3.0.
In my script I check for validity in dictionary key values, like so:
if (
result['application'] in valid_application
and result['environment'] in
valid_environment
and result['fromComponent'] in valid_from
and result['toComponent'] in valid_to
and result['messageComponent'] in
valid_messageComponent
and result['messageTypeState'] in
valid_messageTypeState
and result['messageType'] in
valid_messageType
) :
flowFile =
session.putAttribute(flowFile, 'isValidMessage', 'True')
else :
flowFile =
session.putAttribute(flowFile, 'isValidMessage', 'False')
I curl an Http POST that populates all the key values. When they are
all there, the script works wonderfully. But when any one has no value
in the incoming json submitted via POST, it throws an error. For
example, like so , "messageComponent":""
The error thrown and logged by NiFi to nifi-app.log is this:
2017-07-12 01:03:55,578 ERROR [Timer-Driven Process Thread-3]
o.a.nifi.processors.script.ExecuteScript
ExecuteScript[id=61381fb9-1012-115d-2a56-9f9e7fe9f382] Failed to
process session due to
org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: KeyError: 'environment' in <script> at
line number 254: {}
org.apache.nifi.processor.exception.ProcessException:
javax.script.ScriptException: KeyError: 'environment' in <script> at
line number 254
at
org.apache.nifi.processors.script.ExecuteScript.onTrigger(ExecuteScript.java:230)
at
org.apache.nifi.controller.StandardProcessorNode.onTrigger(StandardProcessorNode.java:1120)
at
org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:147)
at
org.apache.nifi.controller.tasks.ContinuallyRunProcessorTask.call(ContinuallyRunProcessorTask.java:47)
at
org.apache.nifi.controller.scheduling.TimerDrivenSchedulingAgent$1.run(TimerDrivenSchedulingAgent.java:132)
at
java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at
java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at
java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.script.ScriptException: KeyError: 'environment' in
<script> at line number 254
at
org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:202)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:42)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
at
javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
at
org.apache.nifi.script.impl.JythonScriptEngineConfigurator.eval(JythonScriptEngineConfigurator.java:59)
at
org.apache.nifi.processors.script.ExecuteScript.onTrigger(ExecuteScript.java:220)
... 11 common frames omitted
Caused by: org.python.core.PyException: null
at org.python.core.Py.KeyError(Py.java:249)
at org.python.core.PyObject.__getitem__(PyObject.java:738)
at org.python.pycode._pyx15333737.f$0(<script>:245)
at org.python.pycode._pyx15333737.call_function(<script>)
at org.python.core.PyTableCode.call(PyTableCode.java:167)
at org.python.core.PyCode.call(PyCode.java:18)
at org.python.core.Py.runCode(Py.java:1386)
at org.python.core.__builtin__.eval(__builtin__.java:497)
at org.python.core.__builtin__.eval(__builtin__.java:501)
at
org.python.util.PythonInterpreter.eval(PythonInterpreter.java:259)
at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:40)
... 15 common frames omitted
What can I do to avoid this error, since I am unable to determine why
the empty incoming value is causing it to occur?
Thanks in advance for your help.
Cheers,
Jim