Dataweave passing varaible to url mulesoft - if-statement

I'm trying pass the queryParams dynamically to request depending from user what put in postman.
Here is the transform message with variable name jql (this variable I would like then pass in url)
<ee:transform doc:name="Transform Message" >
<ee:message>
</ee:message>
<ee:variables>
<ee:set-variable variableName="queryParams" ><![CDATA[
{
"demo" : attributes.queryParams['demo'] default "",
"demo2": attributes.queryParams['demo2'] default "",
"demo3" :attributes.queryParams['demo3'] default ""
}
]]></ee:set-variable>
<ee:transform doc:name="Transform Message" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="jql" ><![CDATA[
if(vars.queryParams.demo != null and vars.queryParams.demo2 == null and vars.queryParams.demo3 == null)
"demo= " ++ vars.queryParams.demo
else if(vars.queryParams.demo2 != null and vars.queryParams.demo3 == null and vars.queryParams.demo == null)
"demo2 = " ++ vars.queryParams.demo2
else if(vars.queryParams.demo != null and vars.queryParams.demo2 != null and vars.queryParams.demo3 == null )
"demo= " ++ vars.queryParams.demo ++ " and demo2 = " ++ vars.queryParams.demo2
]]></ee:set-variable>
</ee:variables>
</ee:transform>
<http:request method="GET" doc:name="Request" config-ref="HTTP_Request_configuration" path="/demo/search">
<http:query-params><![CDATA[#[output application/java
---
{
"jql" : vars.jql
}]]]></http:query-params>
</http:request>
And for example if user put only parameter demo I would like only this "demo = demo" etc.
In this case I got 400 like this:
Message : HTTP GET on resource 'https://demo/search' failed: bad request (400).
Element : searchForIssuesUsingJQL/processors/2 # jira:jira.xml:160 (Request)
Element DSL : <http:request method="GET"
doc:name="Request" config-ref="HTTP_Request_configuration" path="demo/search">
<http:query-params>#[output application/java
---
{
"jql" : vars.jql
}]</http:query-params>
</http:request>
Error type : HTTP:BAD_REQUEST

That's not a good way to implement it and it doesn't even cover all possible cases. Better make it dynamic. Let's convert vars.QueryParams into a list for easier manipulation and then reduce it into a single strings, adding " and " to separate elements when the accumulator is not empty:
vars.queryParams
filterObject (sizeOf($) > 0)
pluck ((value, key, index) -> {k: key, v:value})
map ($.k ++ "=" ++ $.v)
joinBy " and "
With this method you don't even need to know if it contains a specific string.

Related

Lotus Notes - Change Value in Document from View

Does anyone have code that replaces a value in selected document of a view using a customized icon on the toolbar. I remember this was done using Formulas but cannot find anymore on the web.
Thanks,
Tim
Create a custom icon in the toolbar preferences and put this code in the formula window. Show the icon in all views. While in a view, it will prompt you for the field, its type and its value. Then it will replace that value in the field without ever opening the document.
Found this in one of the public Lotus Notes forums a long time ago. If anyone knows the original creator, please name them here for credit they deserve.
REM {Get a listing of all the fields on the current document};
List := #DocFields;
REM {Possible data types to choose from.};
REM {I called Number Integer because use keyboard to select what you want with keyboard quicker.};
DataTypes := "Text" : "Date" : "Integer" : "Password" : "Name" : "Common Name" : "**** Remove Field ****" : "Text Multi Value" : "Date Multi Value" : "Integer Multi Value" : "Name Multi Value";
REM {Prompt for which field needs to be updated.};
EditField := #Prompt([OkCancelList]; "Select Field To Update"; "Select the field you wish to update:"; ""; List : "**** ADD A NEW FIELD ****");
REM {If adding a new field, prompt for the field name};
NewFieldName := #If(EditField = "**** ADD A NEW FIELD ****"; #Prompt([OkCancelEdit]; "Enter Field Name"; "Enter the name of the new field:"; ""); "");
CheckFieldName := #If(#IsMember(NewFieldName; List) & NewFieldName != ""; #Return(#Prompt([Ok]; "Already In List"; "The field " + NewFieldName + " already exists on the document.")); "");
UpdateVariable := #If(NewFieldName = ""; ""; EditField := NewFieldName);
REM {Prompt for which data type you would like the data to be};
REM {This needs to be done before value prompt to determine if the};
REM { Picklist or any prompting needs to be used.};
DataType := #Prompt([OkCancelList] : [NoSort]; "Choose Data Type"; "Please Select the correct data type or action for field: " + EditField; "Text"; DataTypes);
REM {For multi-valued fields, let the user choose the separator to use};
Separator := #If(#Contains(DataType; "Multi Value"); #Prompt([OkCancelList] : [NoSort]; "Choose Separator"; "Choose the separator to split out your multiple values"; ":"; (":" : ";" : "+" : "-" : "*")); "");
REM {Pull out the current value of the field};
CurrValue1 := #Eval(#Text(EditField));
CurrValue2 := #Abstract([TextOnly]; 254; ""; #Text(EditField));
CurrValue := #If(#IsNumber(CurrValue1) | #IsTime(CurrValue1); #Implode(#Text(CurrValue1); Separator); CurrValue2 != ""; CurrValue2; #Implode(#Text(CurrValue1); Separator));
REM {Based on what type of data is being entered different prompts will happen if any at all.};
RawValue := #If(
#Contains(DataType; "Name Multi Value"); #PickList([Name]);
#Contains(DataType; "Name"); #PickList([Name] : [Single]);
DataType = "**** Remove Field ****"; "";
#Contains(DataType; "Multi Value"); #Prompt([OkCancelEdit]; "New Value"; "Please enter the new desired value for: " + EditField + " seperated with " + Separator + " for each value."; CurrValue);
#Prompt([OkCancelEdit]; "New Value"; "Please enter the new desired value for: " + EditField + "."; CurrValue)
);
REM {If data conversion doesn't work then don't set field.};
#If(
DataType = "Date"; #If(#SetField(EditField; #TextToTime(RawValue)));
DataType = "Integer"; #If(#IsError(#TextToNumber(RawValue)); ""; #SetField(EditField; #TextToNumber(RawValue)));
DataType = "Password"; #SetField(EditField; #Password(RawValue));
DataType = "**** Remove Field ****"; #SetField(EditField; #DeleteField);
DataType = "Text Multi Value"; #SetField(EditField; #Explode(RawValue; Separator));
DataType = "Date Multi Value"; #SetField(EditField; #TextToTime(#Explode(RawValue; Separator)));
DataType = "Integer Multi Value"; #If(#IsError(#TextToNumber(#Explode(RawValue; Separator))); ""; #SetField(EditField; #TextToNumber(#Explode(RawValue; Separator))));
DataType = "Name Multi Value"; #SetField(EditField; #Explode(#Name([Canonicalize]; RawValue); Separator));
#SetField(EditField; RawValue)
);
""

How to edit list elements in kotlin or add to second list?

I tried to edit a list in-place but wasn't able to get it working. Now trying to edit individual elements and add them to a second list. However the second list remains null and does not get updated. Any help would be appreciated.
var localFiles: MutableList<String> = File(localPath).list().toMutableList()
var localFileDates: MutableList<String>? = null
val iterateLocal = localFileDates?.listIterator()
for (item in localFiles) {
var date = item.takeLast(10).take(6)
if (date.matches("[0-9]+".toRegex()) and (date.length == 6) and (date != null) and (date != "null")) {
iterateLocal?.add(item.takeLast(10).take(6))
}
}
println(networkFiles) // prints correct outpu
println(localFileDates) // prints null
You need init localFileDates variable:
var localFileDates = MutableList()
var localFiles: MutableList<String> = File(localPath).list().toMutableList()
var localFileDates = MutableList<String>()
val iterateLocal = localFileDates?.listIterator()
for (item in localFiles) {
var date = item.takeLast(10).take(6)
if (date.matches("[0-9]+".toRegex()) and (date.length == 6) and (date != null) and (date != "null")) {
iterateLocal?.add(item.takeLast(10).take(6))
}
}
println(networkFiles) // prints correct outpu
println(localFileDates) // prints correct
It is better to use map{..} function to create a copy of the list with updated values.
val localFiles = File(localPath).list()?.toMutableList() ?: listOf()
val localFileDates = localFiles.mapNotNull { item ->
val date = item.takeLast(10).take(6)
if (date.matches("[0-9]{6}".toRegex()) {
date
} else {
null
}
}
println(localFiles)
println(localFileDates)
I use the mapNotNull{..} function calls the block for every element of the list and builds the new list only from non-null values.
You do not need var in your code, explicit type names can be omitted too.
The condition can be simplified - no need for the null check, the regular expression filters our the data == "null" case, the length check can be included into the regex too. The date variable can be re-used too.
A more idiomatic (and readable) way:
val localFileDates = File(localPath).list().map { it.takeLast(10).take(6) }.filter {
it.matches("[0-9]+".toRegex()) && (it.length == 6) && (it != "null")
}
Also I suggest you create a named function for takeLast(10).take(6) and the condition to make it clear what is the intent of these lines of code.

parse and replace a list of object in kotlin

I am currently having a list of obeject defined as:
fun updateList(tools: List<Tool>, updateTools: List<Updated>){
... code below
}
the Tool data class is defined as:
data class Tool(
var id: String = ""
var description: String = ""
var assignedTo: String = ""
)
the Updated data class is defined as:
data class Updated(
var id: String = ""
var assignedTo: String = ""
)
Basically, I parse the list updateTools and if I found a id match in tools, I update the assignedTo field from the Tool type object from tools by the one from updateTools
fun updateList(tools: List<Tool>, updateTools: List<Updated>){
updateTools.forEach{
val idToSearch = it.id
val nameToReplace = it.name
tools.find(){
if(it.id == idToSearch){it.name=nameToReplace}
}
}
return tools
}
it's not working but I do not see how to make it easier to work. I just started kotlin and I feel that it's not the good way to do it
any idea ?
Thanks
First of all:
you're not assigning assignedTo, you're assigning name...
in the predicate passed to find, which
should only return a Boolean value to filter elements, and
should probably not have any side effects,
those should be done later with a call to i.e. forEach.
Additionally, your constructor parameters to the data class are normal parameters, and as such, need commas between them!
Your last code block, corrected, would be:
updateTools.forEach {
val idToSearch = it.id
val nameToReplace = it.name
tools.find { it.id == idToSearch }.forEach { it.assignedTo = nameToReplace }
}
return tools
I'd do it like this (shorter):
updateTools.forEach { u -> tools.filter { it.id == u.id }.forEach { it.assignedTo = u.name } }
This loops through each update, filters tools for tools with the right ID, and sets the name of each of these tools.
I use forEach as filter returns a List<Tool>.
If you can guarantee that id is unique, you can do it like this instead:
updateTools.forEach { u -> tools.find { it.id == u.id }?.assignedTo = u.name }
firstOrNull returns the first element matching the condition, or null if there is none. Edit: it seems find is firstOrNull - its implementation just calls firstOrNull.
The ?. safe call operator returns null if the left operand is null, otherwise, it calls the method.
For = and other operators which return Unit (i.e. void, nothing), using the safe call operator simply does nothing if the left operand is null.
If we combine these, it effectively sets the name of the first element which matches this condition.
First, you're missing comma after properties in your data classes, so it should be:
data class Tool(
var id: String = "",
var description: String = "",
var assignedTo: String = ""
)
data class Updated(
var id: String = "",
var assignedTo: String = ""
)
As for second problem, there're probably number of ways to do that, but I've only corrected your idea:
fun updateList(tools: List<Tool>, updateTools: List<Updated>): List<Tool> {
updateTools.forEach{ ut ->
tools.find { it.id == ut.id }?.assignedTo = ut.assignedTo
}
return tools
}
Instead of assigning values to variables, you can name parameter for forEach and use it in rest of the loop.

How do you set up Automatic Recurring Billing (ARB) for Authorize.net using the AuthnetARB class

I was able to use the class to set up ARB for payments made with credit cards like below:
include_once('includes/AuthnetARB.class.php');
$total_payments = intval($_SESSION['total_payments']) - 1;
$start_date = date("Y-m-d", strtotime("+ ".($_SESSION['payment_type'] < "12" ? $_SESSION['payment_type'] : '1')." ".($_SESSION['payment_type'] == "12" ? 'year' : ($_SESSION['payment_type'] == "7" ? 'day' : 'month')).($total_payments > 1 ? 's' : '')));
$subscription = new AuthnetARB("[you-no-see]","[you-no-see]", false);
$subscription->setParameter('amount', number_format($total_cost, 2,'.',''));
$subscription->setParameter('cardNumber', str_replace(array(" ","-"),"",$_SESSION['CCNumber']));
$subscription->setParameter('expirationDate', "20".$_SESSION['CCExpireYear']."-".$_SESSION['CCExpireMonth']);
$subscription->setParameter('firstName', str_replace("&","",$billFname));
$subscription->setParameter('lastName', str_replace("&","",$billLname));
$subscription->setParameter('address', substr($billAddress,0,50));
$subscription->setParameter('city', $billCity);
$subscription->setParameter('state', $billState);
$subscription->setParameter('zip', $billZip);
$subscription->setParameter('email', $_SESSION['email']);
$subscription->setParameter('interval_unit', ($_SESSION['payment_type'] == "12" ? 'years' : ($_SESSION['payment_type'] == "7" ? 'days' : 'months')));
$subscription->setParameter('interval_length', ($_SESSION['payment_type'] == "12" ? '1' : $_SESSION['payment_type']));
$subscription->setParameter('totalOccurrences', $total_payments);
$subscription->setParameter('startDate', $start_date);
$subscription->setParameter('trialOccurrences', 0);
$subscription->setParameter('trialAmount', 0);
// Create the subscription
$subscription->createAccount();
if ($subscription->isSuccessful())
{
// Get the subscription ID
$subscription_id = $subscription->getSubscriberID();
$_SESSION['subscription_id'] = $subscription_id;
$result = mysql_query("UPDATE donations SET subscription_id='".mysql_real_escape_string($subscription_id)."', subscription_interval='".$_SESSION['total_payments']."', subscription_unit='".$_SESSION['payment_type']."' WHERE did=$did LIMIT 1");
echo mysql_error();
$auth->sendValues();
$recurring_message = "Your first payment has been made, and $total_payments payments of $".number_format($total_cost, 2,'.','')." ".strtolower(getPaymentTypeFromShort($_SESSION['payment_type']))." has been scheduled to start on ".date("m-d-Y", strtotime($start_date)).".\n\n";
}else{
$fd = popen("/usr/sbin/sendmail -t -f[email]","w");
fputs($fd, "To: [email]\n");
fputs($fd, "From: $billFname $billLname <".$_SESSION['email'].">\n");
fputs($fd, "Return-Path: <".$_SESSION['email'].">\n");
fputs($fd, "Subject: CMCC - Failed Recurring Transaction\n");
fputs($fd, "X-Mailer: PHP\n\n\n\n");
fputs($fd, "Client Name: $billFname $billLname");
fputs($fd, "Error: ".$subscription->getResponse()."\n");
fputs($fd, "Failed Transaction: $".number_format($total_cost, 2,'.','')." for ".$_SESSION['total_payments']." ".($_SESSION['payment_type'] == "12" ? 'year' : 'month')."(s)\n\n");
fputs($fd, print_r($subscription, true));
pclose($fd);
$error = array("title" => "Could not process order", "desc" => mysql_real_escape_string($auth->aDBErrors));
insertError($error);
foreach($auth->aErrors as $errMessage) {
$_SESSION['message'] .= "<font color=\"red\">$errMessage</font><br />";
}
$_SESSION['message'] = "<font color=\"red\">".$auth->aResponse['Response Reason Text']."</font>";
$recurring_message = "Future payments could not be set up.\n\n";
}
I altered the above for using echecks as below:
include_once('includes/AuthnetARB.class.php');
$total_payments = intval($_SESSION['total_payments']) - 1;
$start_date = date("Y-m-d", strtotime("+ ".($_SESSION['payment_type'] < "12" ? $_SESSION['payment_type'] : '1')." ".($_SESSION['payment_type'] == "12" ? 'year' : ($_SESSION['payment_type'] == "7" ? 'day' : 'month')).($total_payments > 1 ? 's' : '')));
$subscription = new AuthnetARB("[you-no-see]","[you-no-see]", false);
$subscription->setParameter('amount', number_format($total_cost, 2,'.',''));
$subscription->setParameter("routingNumber", $_SESSION['routing_num']);
$subscription->setParameter("accountNumber", $_SESSION['account_num']);
$subscription->setParameter("accountType", "checking");
$subscription->setParameter("bankNam", $_SESSION['bank_name']);
$subscription->setParameter("nameOnAccount", $shipName);
$subscription->setParameter('firstName', str_replace("&","",$billFname));
$subscription->setParameter('lastName', str_replace("&","",$billLname));
$subscription->setParameter('email', $_SESSION['email']);
$subscription->setParameter('interval_unit', ($_SESSION['payment_type'] == "12" ? 'years' : ($_SESSION['payment_type'] == "7" ? 'days' : 'months')));
$subscription->setParameter('interval_length', ($_SESSION['payment_type'] == "12" ? '1' : $_SESSION['payment_type']));
$subscription->setParameter('totalOccurrences', $total_payments);
$subscription->setParameter('startDate', $start_date);
$subscription->setParameter('trialOccurrences', 0);
$subscription->setParameter('trialAmount', 0);
// Create the subscription
$subscription->createAccount();
if ($subscription->isSuccessful())
{
// Get the subscription ID
$subscription_id = $subscription->getSubscriberID();
$_SESSION['subscription_id'] = $subscription_id;
$result = mysql_query("UPDATE donations SET subscription_id='".mysql_real_escape_string($subscription_id)."', subscription_interval='".$_SESSION['total_payments']."', subscription_unit='".$_SESSION['payment_type']."' WHERE did=$did LIMIT 1");
echo mysql_error();
$auth->sendValues();
$recurring_message = "Your first payment has been made, and $total_payments payments of $".number_format($total_cost, 2,'.','')." ".strtolower(getPaymentTypeFromShort($_SESSION['payment_type']))." has been scheduled to start on ".date("m-d-Y", strtotime($start_date)).".\n\n";
}else{
$fd = popen("/usr/sbin/sendmail -t -f[email]","w");
fputs($fd, "To: [email]\n");
fputs($fd, "From: $billFname $billLname <".$_SESSION['email'].">\n");
fputs($fd, "Return-Path: <".$_SESSION['email'].">\n");
fputs($fd, "Subject: CMCC - Failed Recurring Transaction\n");
fputs($fd, "X-Mailer: PHP\n\n\n\n");
fputs($fd, "Client Name: $billFname $billLname");
fputs($fd, "Error: ".$subscription->getResponse()."\n");
fputs($fd, "Failed Transaction: $".number_format($total_cost, 2,'.','')." for ".$_SESSION['total_payments']." ".($_SESSION['payment_type'] == "12" ? 'year' : 'month')."(s)\n\n");
fputs($fd, print_r($subscription, true));
pclose($fd);
$error = array("title" => "Could not process order", "desc" => mysql_real_escape_string($auth->aDBErrors));
insertError($error);
foreach($auth->aErrors as $errMessage) {
$_SESSION['message'] .= "<font color=\"red\">$errMessage</font><br />";
}
$_SESSION['message'] = "<font color=\"red\">".$auth->aResponse['Response Reason Text']."</font>";
$recurring_message = "Future payments could not be set up.\n\n";
}
However, this did not work. Instead of trying to process it as an echeck, it tried processing it as a credit card. Since it could not it failed. My question is: How do I force this to process as an echeck instead of credit?
I was already so close. I could not find this answer anywhere, so thought I'd share my dilemma and answer here. I needed only to specify true for the createAccount() function which tells the class that it is an eCheck. Silly me was searching all over the web instead of just searching the class file... Anyway, this is here in case someone else does that too.
$subscription->createAccount(true);

Having a string how to get its contents from first `/r/n/r/n` until 2 lines from string end?

I try to create simple file upload service in C++. I get all user request body as one big string. User can upload any type of data. I need to get only user file contents from request boby string.
so for example now I have next code working with my service API provider:
std::cout << "Request body: " << request->body << std::endl << "Request size: " << request->body.length() << std::endl;
and this would print as:
Request body: ------WebKitFormBoundaryAZlJcLinxYi6OCzX
Content-Disposition: form-data; name="datafile"; filename="crossdomain.xml"
Content-Type: text/xml
я╗┐<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-
omain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="*" />
</cross-domain-policy>
------WebKitFormBoundaryAZlJcLinxYi6OCzX--
Request size: 411
So I need to get from request->body (which is string) all data from first /r/n/r/n until last line -2 lines. How to do such thing with string in C++?
This isn't the most elegant approach, but one option would be to do something like this:
std::string contents = /* ... get the string ... */
/* Locate the start point. */
unsigned startPoint = contents.find("\r\n\r\n");
if (startPoint == string::npos) throw runtime_error("Malformed string.");
/* Locate the end point by finding the last newline, then backing up
* to the newline before that.
*/
unsigned endPoint = contents.rfind('\n');
if (endPoint == string::npos || endPoint == 0) throw runtime_error("Malformed string.");
endPoint = contents.rfind('\n', endPoint - 1);
if (endPoint == string::npos) throw runtime_error("Malformed string.");
/* Hand back that slice of the string. */
return std::string(contents.begin() + startPoint, contents.begin() + endPoint);
You can use regular expressions for that. This page has some nice c++ examples: http://www.math.utah.edu/docs/info/libg++_19.html