I have updated the variable registry to point to a custom properties file and i am able to read those in my processors using expression language with out any issues.
How ever i want to read them in my Custom Processor's (extending the AbstractProcessor) onTrigger()
I tried flowFile.getAttributes() and context.getAllProperties() and it is not getting picked up.
Appreciate any inputs.
Thanks
To clarify, you want to reference the value of these externally-defined variables inside the application logic of your CustomProcessor#onTrigger() method?
You can:
Load the variable definitions by querying NiFiProperties#getVariableRegistryProperties() or NiFiProperties#getVariableRegistryPropertiesPaths. Once you have a reference to the variable definitions, you can parse and use them as you wish.
You can reference them via the flowfile attributes or processor properties if those attributes or properties support Expression Language and it is appropriately scoped. The PropertyDescriptor will list expressionLanguageSupported() and return an ExpressionLanguageScope, which is an enum consisting of NONE, VARIABLE_REGISTRY, and FLOWFILE_ATTRIBUTES (which also includes the VR).
I don't understand the scenario where you want your code to load custom variables that aren't controllable by the flow administrator, which would be populated via processor properties or flowfile attributes. If you really feel you need to access custom variables that aren't available via the context or flowfile, you can use Option 1 above, but you could also theoretically store those variables in environment variables, System properties, etc.
Related
I need to create a Nifi (v1.17.0) custom processor with a property having several possible values. These values are generated during the execution of the previous processors in the flow.
The flow is as follows:
Processor A : Generate a yaml file.
Processor B : (the one I've been trying to create) Get the values in the yaml file generated previously and use them to populate a property in order to let the user select the one he needs. The process will then be adapted depending on the value selected.
I've found a solution based on the property method identifiesControllerService(DistributedMapCacheClient.class). It offers the possibility to have a property based on a dropdown menu with several possible choice (use a controller service or parameter contexts).
My idea is to use a parameter contexts available for the processor. So I would like to add the values I need in a Parameter context. This has to be done in the Processor A (which is also a custom processor) in order to use them in the property in the Processor B.
But I didn't find any way to add a parameter in the Parameter context programmaticaly in the onTrigger method of the Processor A. How can I add this parameter?
Context
I am developing a custom JMeter plugin which generates test data dynamically from a tree like structure.
The editor for the tree generates GUI input fields as needed, and therefore I have no set of defined configuration properties which are set in the respective TestElement. Instead, I serialize the tree as a whole in the GUI class, set the result as one property and deserialize it in the config element where it is processed further during test execution.
Problem
This works just fine, except that JMeter variable/function expressions like ${foo} or ${_bar(..)} in the dynamic input fields are not evaluated. As far as I understand the JMeter source code, the evaluation is triggered somehow if the respective property setters in org.apache.jmeter.testelement.TestElement are used which is not possible for my plugin.
Unfortunately, I was not able to find a proper implementation which can be used in my config element to evaluate such expressions explicitly after deserialization.
Question
I need a pointer to JMeter source code or documentation for evaluating variable/function expressions explicitly.
After I manages to setup the JMeter-Project properly in my IDE, I found org.apache.jmeter.engine.util.CompoundVariable which can be used like this:
CompoundVariable compoundVariable = new CompoundVariable();
compoundVariable.setParameters("${foo}");
// returns the value of the expression in the current context
compoundVariable.execute();
I want to declare a variable whose value can be displayed anywhere in app (on any page) and can be modified from any micro flow. how can we do that??
As all mutable values in mendix are represented by attributes in an entity, you need to create an entity in order to be able to modify a value. The closest thing to a global variable in Mendix is an attribute on a singleton entity.
Let's suppose we want to be able to change the some settings of your app through its UI or within a microflow. To do this we can create an 'AppSettings' entity with attributes for all the different "global variables" that need to be set.
To make it a singleton entity we need to make sure that there is only one object of its kind in the database. To do this it's a common practice to implement a 'GetOrCreate' microflow that retrieves the 'AppConfiguration' object from the database and creates one if there is none yet.
We can now use 'GetOrCreateAppConfiguration' anywhere, where we need to read or modify our app settings, such as a microflow.
Using'GetOrCreateAppConfiguration' we could also create and settings page, where admins can modify the AppConfiguration attributes using a DataView with a Microflow retrieve.
We can also use a dataview to display the AppName "global variable" to users and use conditional visibility based on feature flag "global variables" to show or hide UI elements. Note that this means that we should probably not to give regular users write access to 'AppConfiguration' attributes.
I couldn't find any reference with this functionality. Shall I just implement a helper method in the builder to read fields in StateTransition object and populate the chain configureTransition() call by myself??
Just to confirm not to reinvent the wheels.
UPDATE:
I'm trying to use StateMachineBuilder to configure with some pre-defined states and transitions in a properties file. In Builder, they use this chained call to generate configuration:
builder.configureTransitions().withExternal().source(s1)....
What I have in mind is, everything read from the file is stored in an object, the spring sm library has this StateTransition object. But as far as I know from the API, there is no way to use it directly to configure a state machine. Instead, I can read individual fields in the object and use the chained call above.
Thanks!
If you want to do it like that, what you mentioned is pretty much only option. Hopefully we get a real support for external state machine definition, i.e. tracked in https://github.com/spring-projects/spring-statemachine/issues/78.
In order to allow us dynamic control over labels and error messages, we created a custom DataAnnotationsModelMetadataProvider. In a Display attribute we store the key in the Name property and using the custom DataAnnotationsModelMetadataProvider we substitute the key for a string value from our custom CMS. The problem is that we now have two sets of values. One for Web views and one for mobile views. At runtime we check if the client is on a mobile device and substitute the values accordingly.
After test running this setup I came across a strange issue. When the AppDomain is first created and the Name properties of the different data annotations are replaced with the string values, everything works fine. In debug, when I enter the custom DataAnnotationsModelMetadataProvider for a second time, I see the name properties already populated with the values I had substituted the previous run. This was strange to me, since it was my understanding that data annotation propeties could not be chnaged at runtime. It now seems like there is a model metadata cache happening somewhere. Since I based my custom solution on replacing the values each time the DataAnnotationsModelMetadataProvider is called upon, I would like to disable this caching, if possible.
For now I started using the ShortName property as my key storing property and I replace the Name property, and this way I can repopulate the strings on each run. But this was not the initial design and I don't have such a key store property for ValidationAttributes.
So is there a way to disable this cache? I don't need the cache for the sake of caching, since all CMS data is cached in memory in another layer anyway.