Is there alternative way to access session details in deferred custom action? - session

I have a custom action and need to get below values for copying some parts from installation folder to VS2010 folder
VS2010 directory path (VS2010DEVENV property)
Installation path (INSTALLLOCATION property)
To give enough privileges, I've set custom action as Execute='deferred' Impersonate='no'. But when running the installer, it logged the message:
Cannot access session details from a non-immediate custom action
It seems we cannot access a property in a "deferred" custom action (i.e session["VS2010DEVENV"])
Is there any other way so that I can retrieve those values as needed?

This must be helpful. Pay special attention to the bottom of the page, a guideline of 2 steps how to pass values via CustomActionData.
Here is the excerpt:
To write the value of a property into the installation script for use
during a deferred execution custom action:
Insert a small custom action into the installation sequence that sets the property of interest to a property having the same name as
the deferred execution custom action. For example, if the primary key
for the deferred execution custom action is "MyAction" set a property
named "MyAction" to the property X which you need to retrieve. You
must set the "MyAction" property in the installation sequence before
the "MyAction" custom action. Although any type of custom action can
set the context data, the simplest method is to use a property
assignment custom action (for example Custom Action Type 51).
At the time when the installation sequence is processed, the installer will write the value of property X into the execution script
as the value of the property CustomActionData.

Additional details: multiple property values can be passed by using the following syntax in a "Custom Action Type 51" (which is basically just a custom action that sets a property value):
PROPERTY1=Value1;PROPERTY2=Value2;PROPERTY3=...
Values can be retrieved from within the custom action like this:
string prop1 = session.CustomActionData["PROPERTY1"];
string prop2 = session.CustomActionData["PROPERTY2"];
Here's an example that sets property values for a custom action with ID "MyCustomAction":
<CustomAction
Id="SetCustomActionPropertyValues"
Property="MyCustomAction"
Value="INSTALLDIR=[INSTALLDIR];EXECUTABLE=[#MyExecutableFile]" />
(read this MSDN article for more details on the formatted syntax which in this example is used to retrieve the install location of a file with ID "MyExecutableFile")

Related

Power Automate: Run a child flow by GUID

I'm trying to call a child flow from a Power Automate flow by it's guid (by using an Expression in the Child Flow dropdown), instead of hardcoding the child flow selection.
However, whenever I try to save the parent flow, I get the following error:
Request to XRM API failed with error: 'Message: Flow client error returned with status code "BadRequest" and details "{"error":{"code":"ChildFlowIdNotValid","message":"The workflow id '[[expression]]' is not a valid child flow id. The id must be a valid GUID."}}". Code: 0x80060467
I tried various expression, even simple stuff like #guid() (which is definitely a valid guid), but to no avail.
It seems like the platform performs a "compile time" check on the value, which makes using any dynamic value impossible.
Any ideas?
I think that Run Child flow action is designed to be more interactive than programmable, unfortunately. Interacting with the Run Child Flow action calls an API, and the response is used to modify the action definition. Whatever is the "custom value" expression - it is not evaluated, but instead read as string, and used in a call to retrieve the sample header. That sample is then used to re-format the Run Child Flow action to show the appropriate headers.
Having an undetermined target would mean the call body is not defined, which could be a problem. Interestingly, it does pop a spot for a body when initially trying to look for a hard-coded GUID.
You can see the after-effect of this behavior in how even hardcoded GUIDs get replaced with the flow names once saved/reopened.
As a workaround, I stack Run Child flows in a Switch action checking an expression result. I.e.:
Switch workaround
Side note - GUID() in Azure Logic Apps (and powerautomate) does not format an arbitrary string as GUID.

Accessing Cognito Custom Attributes in a post-confirmation lambda function

I have a post-confirmation lambda function that writes user attribute information to a dynamoDB table. I've managed to get access to standard user attributes fields in the "event" parameter by doing stuff like
event.request.userAttributes.sub
but trying to run
event.request.userAttributes.role //where role is the name of my custom attribute
doesn't seem to work. Anyone know what the proper syntax for this is? And do I need to set any special read permissions for custom attributes? I created this custom attribute a long time after I originally made this user pool, if that changes things.
All custom attributes are prefixed with the custom: prefix (Documentation - Custom Attributes).
Therefore (I'll assume you're using JavaScript here- if not feel free to specify and I can change this example), you'd need to use:
event.request.userAttributes['custom:role']
You don't need to set any special read permissions- all the user attributes are returned in the PostConfirmation lambda.

InferAvroSchema Avro Record Name based on flow attribute

I have a common process group that will infer avro schema based on the file i supplied. But I want to set the Avro Record Name to a name corresponding to the filename i am supplying. So I used ${filename}. But the InferAvroSchema got error saying the record name is empty. Note that before this, I already set the property "filename" to the flowfile attribute and it has a value since i tested it using ReplaceText to see if there's value for ${filename}
Unfortunately this looks like a bug in InferAvroSchema. Many of the properties support expression language, but then the processor doesn't evaluate them against the incoming flow file. So it ends up only being able to use a value typed directly into the property (non-EL), or a value from system or environment properties which doesn't really make sense for a lot of these properties.
I created this JIRA for the issue:
https://issues.apache.org/jira/browse/NIFI-2465
The fix is that all of the calls to evaluateAttributeExpressions() should be passing in a flow file like:
context.getProperty(CSV_HEADER_DEFINITION).evaluateAttributeExpressions(inputFlowFile).getValue()

Web API action cache

I am implementing a cache mechanism for some WebAPI actions. i found the following option is useful but i am not sure its the best way:
I am going to use context.Cache["[Here i will set the action name and the values of all the parameters passed to the action]"] = [here i will set the result i got from the database] in a Filter i will build.
The action filter will search the string of the action name and the parameters in the context.Cache collection. if exists, will return the data instead of executing the original action.
Is that the best approach?
Btw, i prefer to not use any 3rd party libraries.

Backbone.js: run validations and fire error events on set, but don't abort set if validations fail

I've got a Backbone model with a custom validate method that validates the format of one of a the model's attributes. My model is hooked up to a view that exposes said attribute via a text field. The view has a 'save' button that the user must explicitly press to save the model changes back to the server.
When the user types an invalid attribute value, I want to visually mark the field as being in an invalid state. So far, easy - I can bind the change event of the input field to a function that calls myModel.set({ attribute: value }), and listen for the "error" event on the model to tell when the validation has failed and I should mark the input as invalid.
The problem comes when I want to handle the save button click. Because Backbone.Model.set aborts actually setting the attributes on the model if validation fails, my model will not accurately reflect the value the user has entered unless the value is valid. When the user clicks save after typing in an invalid value, I check whether the model is valid, find that it is (because the invalid attribute was never actually set), and save the old (valid) attribute value to the server.
What it seems like I want is a version of set that always makes the requested changes, but also still triggers validations and events. set(..., { silent: true }) will allow the change to go through, but will not run validations or trigger events.
In short - I want my model to sometimes exist in an invalid state (if the user has entered invalid attribute values), and I want to be able to get events when it transitions between valid and invalid. Is there a graceful way to do this with backbone, or am I thinking about this completely wrong?
I suggest you use this backbone validation plugin https://github.com/thedersen/backbone.validation
Extremely helpful.
For your usecase (to allow values to be set even if they are invalid),
you just need to do override the set function of your model.
set: function (key, value, options) {
options || (options = {});
options = _.extend(options, { forceUpdate: true });
return Backbone.Model.prototype.set.call(this, key, value, options);
}
The 'forceUpdate' property of backbone.validation allows the validate method to return true, while still calling for validations.
After the save click, you can call,
var errors = model.validate(model.validate.attributes);
This will return all the errors that your model has and you can appropriately display them.
You also have callbacks for valid and invalid which you can use freely
What I've done with this sort of validation is to reset the models attributes from the inputs before save on the save click (only doing the save if the set doesn't fail)
This way the save button click re triggers the validation - triggering the error.
It means the model is always valid and you cant progress to the next page until the input is all valid.

Resources