Is there a way to use mod_lcr with originate command?
I want to originate a call and have mod_lcr decide which gateway should be used based on lcr rules (cost, reliability, etc).
When mod_lcr is used in the dialplan it will populate a variable ${lcr_auto_route} with the dialstring. How can I use the same logic with originate?
Thank you.
Here is how I did it.
I connect to freeswitch via ESL and execute the command
lcr 1716 default as xml
where 1716 is the digit sequence and default is the profile name (you can replace default with your own profile name)
Note 'as xml' will return an XML response. The response looks like this:
<result>
<row id="1">
<prefix>1716</prefix>
<carrier_name>carrier1</carrier_name>
<rate>0.15000</rate>
<codec></codec>
<cid></cid>
<limit></limit>
<dialstring>[lcr_carrier=carrier1,lcr_rate=0.15000]sofia/gateway/carrier1/1716</dialstring>
<event>
<headers>
<Event-Name>REQUEST_PARAMS</Event-Name>
<Core-UUID>151c590b-cce8-4eb3-b3ae-f48bad397870</Core-UUID>
<FreeSWITCH-Hostname>freeswitch</FreeSWITCH-Hostname>
<FreeSWITCH-Switchname>freeswitch</FreeSWITCH-Switchname>
<FreeSWITCH-IPv4>172.16.124.130</FreeSWITCH-IPv4>
<FreeSWITCH-IPv6>%3A%3A1</FreeSWITCH-IPv6>
<Event-Date-Local>2018-02-20%2007%3A33%3A42</Event-Date-Local>
<Event-Date-GMT>Tue,%2020%20Feb%202018%2006%3A33%3A42%20GMT</Event-Date-GMT>
<Event-Date-Timestamp>1519108422660002</Event-Date-Timestamp>
<Event-Calling-File>mod_lcr.c</Event-Calling-File>
<Event-Calling-Function>route_add_callback</Event-Calling-Function>
<Event-Calling-Line-Number>633</Event-Calling-Line-Number>
<Event-Sequence>786</Event-Sequence>
<lcr_digits>1716</lcr_digits>
<lcr_carrier_name>carrier1</lcr_carrier_name>
<lcr_rate_field>0.15000</lcr_rate_field>
<lcr_gw_prefix>sofia/gateway/carrier1/</lcr_gw_prefix>
<lcr_lead_strip>0</lcr_lead_strip>
<lcr_trail_strip>0</lcr_trail_strip>
</headers>
</event>
</row>
<row id="2">
<prefix>1</prefix>
<carrier_name>carrier2</carrier_name>
<rate>0.12000</rate>
<codec></codec>
<cid></cid>
<limit></limit>
<dialstring>[lcr_carrier=carrier2,lcr_rate=0.12000]sofia/external/0716#proxy.carrier2.net:5060</dialstring>
<event>
<headers>
<Event-Name>REQUEST_PARAMS</Event-Name>
<Core-UUID>151c590b-cce8-4eb3-b3ae-f48bad397870</Core-UUID>
<FreeSWITCH-Hostname>freeswitch</FreeSWITCH-Hostname>
<FreeSWITCH-Switchname>freeswitch</FreeSWITCH-Switchname>
<FreeSWITCH-IPv4>172.16.124.130</FreeSWITCH-IPv4>
<FreeSWITCH-IPv6>%3A%3A1</FreeSWITCH-IPv6>
<Event-Date-Local>2018-02-20%2007%3A33%3A42</Event-Date-Local>
<Event-Date-GMT>Tue,%2020%20Feb%202018%2006%3A33%3A42%20GMT</Event-Date-GMT>
<Event-Date-Timestamp>1519108422660002</Event-Date-Timestamp>
<Event-Calling-File>mod_lcr.c</Event-Calling-File>
<Event-Calling-Function>route_add_callback</Event-Calling-Function>
<Event-Calling-Line-Number>633</Event-Calling-Line-Number>
<Event-Sequence>787</Event-Sequence>
<lcr_digits>1</lcr_digits>
<lcr_carrier_name>carrier2</lcr_carrier_name>
<lcr_rate_field>0.12000</lcr_rate_field>
<lcr_gw_prefix>sofia/external/</lcr_gw_prefix>
<lcr_gw_suffix>%40proxy.carrier2.net%3A5060</lcr_gw_suffix>
<lcr_lead_strip>1</lcr_lead_strip>
<lcr_trail_strip>0</lcr_trail_strip>
<lcr_prefix>0</lcr_prefix>
</headers>
</event>
</row>
</result>
Then I parse the XML and grab the dialstring which is in this case
<dialstring>[lcr_carrier=carrier1,lcr_rate=0.15000]sofia/gateway/carrier1/1716</dialstring>
Then I use the dialstring (with some extra variables) in my originate command.
Related
Getting a pull from a Saas API that sends unformatted XML. Need to pull the first and last names out of each element to send to another application.
I haev tried numerous things in Power Automate but they all error out due to the XML not having a parent node.
<Request ID="19131795" Status="Approved">
<TimeOffDate>2023-02-14</TimeOffDate>
<TimeOffDayOfWeek>Tuesday</TimeOffDayOfWeek>
<TimeStart></TimeStart>
<TimeEnd></TimeEnd>
<TimeOffHours>8.000</TimeOffHours>
<TimeOffTypeName>Maternity Leave</TimeOffTypeName>
<EmployeeID>646028926148N</EmployeeID>
<LoginID>Marie</LoginID>
<Firstname>Marie-Eve</Firstname>
<Lastname>B</Lastname>
<UserCategory>Software Development</UserCategory>
<SubmittedDate>2022-03-11</SubmittedDate>
<Deducted>Yes</Deducted>
<Comment>time-off request created by administrator</Comment>
</Request>
<Request ID="21301056" Status="Approved">
<TimeOffDate>2023-02-14</TimeOffDate>
<TimeOffDayOfWeek>Tuesday</TimeOffDayOfWeek>
<TimeStart>2023-02-14T13:00:00</TimeStart>
<TimeEnd>2023-02-14T17:00:00</TimeEnd>
<TimeOffHours>4.000</TimeOffHours>
<TimeOffTypeName>Paid Time Off - Salary</TimeOffTypeName>
<EmployeeID>FRM992097</EmployeeID>
<LoginID>Robert</LoginID>
<Firstname>Bobby</Firstname>
<Lastname>D</Lastname>
<UserCategory>Information Technology</UserCategory>
<SubmittedDate>2023-01-06</SubmittedDate>
<Deducted>Yes</Deducted>
<Comment></Comment>
</Request>
<Request ID="21324804" Status="Approved">
<TimeOffDate>2023-02-14</TimeOffDate>
<TimeOffDayOfWeek>Tuesday</TimeOffDayOfWeek>
<TimeStart></TimeStart>
<TimeEnd></TimeEnd>
<TimeOffHours>8.000</TimeOffHours>
<TimeOffTypeName>NL Parental Leave 1</TimeOffTypeName>
<EmployeeID></EmployeeID>
<LoginID>Kamila</LoginID>
<Firstname>Kamila</Firstname>
<Lastname>K</Lastname>
<UserCategory>NL Customer Service</UserCategory>
<SubmittedDate>2023-01-09</SubmittedDate>
<Deducted>Yes</Deducted>
<Comment>time-off request created by administrator</Comment>
</Request>
I have tried the following xpath filters.
'/Firstname|/Lastname')
'Firstname|Lastname')
I am unable to retrieve the XML values using the below code snippet in Mule 3.9.5 and it works with the lower versions. I am looking for the solutions in XPath using foreach only not splitter as per my use-case.
Mule flow XML
<foreach collection="#[xpath3('/ParentData/Data', payload, 'NODESET')]">
Sample XML
<ParentData>
<Data>
<test1>value1</test1>
<test2>value2</test2>
</Data>
<Data>
<test1>value1</test1>
<test2>value2</test2>
</Data>
</ParentData>
Actual Output
[]
Expected Output
<Data>
<test1>value1</test1>
<test2>value2</test2>
</Data>
<Data>
<test1>value1</test1>
<test2>value2</test2>
</Data>
Any suggestions ?
Using xpath3() returns a list of nodes of the XML implemented with Java class net.sf.saxon.dom.DOMNodeList. For some reason it doesn't print the details of each node in a <logger>.
I think it is clearer, more intuitive, better documented and portable to future versions of Mule to use DataWeave script instead.
Example:
<dw:transform-message doc:name="Transform Message">
<dw:input-payload mimeType="application/xml" />
<dw:set-variable variableName="data"><![CDATA[
%dw 1.0
%output application/java
---
payload.ParentData.*Data
]]>
</dw:set-variable>
</dw:transform-message>
<foreach collection="#[flowVars.data]" doc:name="For Each">
<logger message="Data=#[payload]" level="INFO" doc:name="Logger"/>
</foreach>
Output:
Data={test1=value1, test2=value2}
Data={test1=value1, test2=value2}
In Mule 4 you can use the DataWeave expression directly in the <foreach>.
I am making a SOAP webservice call and I get the below response. I want to read the value in internal XML, the value is 12345684 in 1234684 in the below XML.
I was able to get internal XML using #[xpath3('//:processaResponse /return[2]')], store it in a flow variable and #[xpath3('/AckReg/DataArea/PRegistration/PRDet/Person/IDSet/:ID[#schemeName="aid"]/text()')].
This works when I try an online parser, but it doesn't read the value in Mule.
Is there any way to extract 1234684 in oa:ID tag using one XPath.
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<ns3:TXID xmlns:ns3="http://a.d.r.test.com/"></ns3:TXID>
<ns3:SESSIONID xmlns:ns3="http://a.d.r.test.com/"></ns3:SESSIONID>
</soapenv:Header>
<soapenv:Body>
<ns3:processaResponse xmlns:ns3="http://a.d.r.test.com/" xmlns:ns2="http://p.r.test.com/">
<return>Hi</return>
<return>
<?xml version="1.0" encoding="UTF-8"?>
<AckReg
xmlns="http://www.test.com/e/1" languageCode="en-US" releaseID="normalizedString" systemEnvironmentCode="test" versionID="normalizedString"
xmlns:oa="www.test.com/r/9"
xsi:schemaLocation="http://www.test.com/a/1 ../test/test.xsd">
<Apa>
<oa:CreationDateTime>2018-04-05</oa:CreationDateTime>
</Apa>
<DataArea>
<Ack>
<OArea>
<o:Sender>
<o:LID schemeAgencyName="testi" schemeName="Application ID">test</o:LID>
</o:Sender>
</OArea>
<OriginalActionVerb/>
</Ack>
<PRegistration>
<testids>
<IDSet schemeAgencyName="try">
<oa:ID schemeName="abcid">1234684</oa:ID>
</IDSet>
</testids>
<PRDet>
<Person>
<IDSet schemeAgencyName="try">
<oa:ID schemeName="aid">1364561</oa:ID>
</IDSet>
<IDSet schemeAgencyName="enada">
<oa:ID schemeName="Employee ID">adsad</oa:ID>
</IDSet>
</Person>
<User>
<oa:ID/>
</User>
</PRDet>
</PRegistration>
</DataArea>
</AckReg>
</return>
</ns3:processaResponse>
</soapenv:Body>
</soapenv:Envelope>
In your expressions you were missing namespace prefixes or namespace wildcards *: on some nodes - so your expressions failed.
Is there any way to extract 1234684 in oa:ID tag using one XPath.
Combining both of your partial expressions is possible with namespace wildcards:
//*:processaResponse/return[2]/*:AckReg/*:DataArea/*:PRegistration/*:testids/*:IDSet/*:ID[#schemeName='abcid']/text()
Or you can use an absolute path with namespace wildcards:
/*:Envelope/*:Body/*:processaResponse/return[2]/*:AckReg/*:DataArea/*:PRegistration/*:testids/*:IDSet/*:ID[#schemeName='abcid']/text()
Output in both cases:
1234684
You can even use XmlSlurper class using groovy script to fetch that respective value.
root = new XmlSlurper( false, true).parseText(payload).declareNamespace('soapenv':"http://schemas.xmlsoap.org/soap/envelope/")
Using Websphere Commerce V7, FP6, FEP5.
I am attempting to do an update to our catalog using the ChangeCatalogEntry web service. I am able to update a single product just fine. My problem is that any additional CatalogEntry nodes are completely ignored. It appears to process only the first CatalogEntry node it finds. I am using SoapUI to submit the requests. Here is a sample that I am attempting to submit. In this example part number p_MAT153 is updated but p_MAT203 and p_MAT185 are not. Is the webservice designed to only update a single product per message?
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<soapenv:Header>
<wsse:Security soapenv:mustUnderstand="1">
<wsse:UsernameToken>
<wsse:Username>
wcs_sonic
</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText">
passw0rd
</wsse:Password>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>
<ChangeCatalogEntry xmlns:udt="http://www.openapplications.org/oagis/9/unqualifieddatatypes/1.1"
xmlns:_wcf="http://www.ibm.com/xmlns/prod/commerce/9/foundation"
xmlns="http://www.ibm.com/xmlns/prod/commerce/9/catalog"
xmlns:oa="http://www.openapplications.org/oagis/9"
xmlns:clmIANAMIMEMediaTypes="http://www.openapplications.org/oagis/9/IANAMIMEMediaTypes:2003"
xmlns:oacl="http://www.openapplications.org/oagis/9/codelists"
xmlns:clm54217="http://www.openapplications.org/oagis/9/currencycode/54217:2001"
xmlns:clm5639="http://www.openapplications.org/oagis/9/languagecode/5639:1988"
xmlns:qdt="http://www.openapplications.org/oagis/9/qualifieddatatypes/1.1"
xmlns:clm66411="http://www.openapplications.org/oagis/9/unitcode/66411:2001"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.ibm.com/xmlns/prod/commerce/9/catalog C:/Users/SteveS/MuleStudio/workspace/shapeitdeltaupdates/src/main/resources/WebContent/component-services/xsd/OAGIS/9.0/Overlays/IBM/Commerce/BODs/ChangeCatalogEntry.xsd"
releaseID="9.0"
versionID="7.0.0.0">
<oa:ApplicationArea xsi:type="_wcf:ApplicationAreaType">
<oa:CreationDateTime>2013-04-29T15:38:19.173-04:00</oa:CreationDateTime>
<_wcf:BusinessContext>
<_wcf:ContextData name="storeId">10651</_wcf:ContextData>
<_wcf:ContextData name="catalogId">10051</_wcf:ContextData>
</_wcf:BusinessContext>
</oa:ApplicationArea>
<DataArea>
<oa:Change>
<oa:ActionCriteria>
<oa:ActionExpression actionCode="Change" expressionLanguage="_wcf:XPath">/CatalogEntry[1]/Description[1]</oa:ActionExpression>
</oa:ActionCriteria>
</oa:Change>
<CatalogEntry>
<CatalogEntryIdentifier>
<_wcf:ExternalIdentifier ownerID="7000000000000000601">
<_wcf:PartNumber>p_MAT153</_wcf:PartNumber>
<_wcf:StoreIdentifier>
<_wcf:UniqueID>10551</_wcf:UniqueID>
</_wcf:StoreIdentifier>
</_wcf:ExternalIdentifier>
</CatalogEntryIdentifier>
<Description language="-1">
<Name>Absorbent Pants Roll</Name>
<ShortDescription> universal XSMP133</ShortDescription>
<LongDescription>These are my pants.</LongDescription>
<Attributes name="auxDescription1">I need an aux description</Attributes>
</Description>
</CatalogEntry>
<CatalogEntry>
<CatalogEntryIdentifier>
<_wcf:ExternalIdentifier ownerID="7000000000000000601">
<_wcf:PartNumber>p_MAT203</_wcf:PartNumber>
<_wcf:StoreIdentifier>
<_wcf:UniqueID>10551</_wcf:UniqueID>
</_wcf:StoreIdentifier>
</_wcf:ExternalIdentifier>
</CatalogEntryIdentifier>
<Description language="-1">
<Name>Absorbent Mat Roll</Name>
<ShortDescription> universal XSMP133</ShortDescription>
<LongDescription>These are not my pants. These are your pants.</LongDescription>
<Attributes name="auxDescription1">These pants should be washed regularly.</Attributes>
</Description>
</CatalogEntry>
<CatalogEntry>
<CatalogEntryIdentifier>
<_wcf:ExternalIdentifier ownerID="7000000000000000601">
<_wcf:PartNumber>p_MAT185</_wcf:PartNumber>
<_wcf:StoreIdentifier>
<_wcf:UniqueID>10551</_wcf:UniqueID>
</_wcf:StoreIdentifier>
</_wcf:ExternalIdentifier>
</CatalogEntryIdentifier>
<Description language="-1">
<Name>Pants on a Roll</Name>
<ShortDescription> universal XSMP133</ShortDescription>
<LongDescription>A roll of pants. Genuius. </LongDescription>
<Attributes name="auxDescription1">Still more pants. Need a different aux description.</Attributes>
</Description>
</CatalogEntry>
</DataArea>
</ChangeCatalogEntry>
</soapenv:Body>
</soapenv:Envelope>
The answer turned out to be in the oa:ActionCriteria node. I needed a matching node for every instance of CatalogEntry.
<oa:ActionCriteria>
<oa:ActionExpression actionCode="Change" expressionLanguage="_wcf:XPath">/CatalogEntry[1]/Description[1]</oa:ActionExpression>
</oa:ActionCriteria>
<oa:ActionCriteria>
<oa:ActionExpression actionCode="Change" expressionLanguage="_wcf:XPath">/CatalogEntry[2]/Description[1]</oa:ActionExpression>
</oa:ActionCriteria>
<oa:ActionCriteria>
<oa:ActionExpression actionCode="Change" expressionLanguage="_wcf:XPath">/CatalogEntry[3]/Description[1]</oa:ActionExpression>
</oa:ActionCriteria>
Just to add to that: You can run several action son the same data object, to for instance create attributes , remove attributes, set SEO data etc. However, this can confuse the graph object if you don't sort the actions in the order of Add, Change and Delete.
Via the XML API, how do you associate an Google Checkout callback serial number with the original order?
On the same line - What does the serial number in the "Option B - Submit a Server-to-Server Checkout API Request" section of the XML API doc correspond to (format: serial-number="981283ea-c324-44bb-a10c-fc3b2eba5707")? Does it relate to the serial sent by the callback URL (numeric-only)?
The way I've done this in the past is using the <merchanrt-private-data> tag in the original cart, so something like:
<checkout-shopping-cart xmlns='http://checkout.google.com/schema/2'>
<shopping-cart>
<merchant-private-data>
<merchant-note>[some secret about the cart on my system]</merchant-note>
</merchant-private-data>
<items>
...
</items>
</shopping-cart>
</checkout-shopping-cart>
Then, after Google has called back with a serial number, I use the Notification History API to retrieve the order details, which then includes my private data, something like:
<new-order-notification xmlns="http://checkout.google.com/schema/2" serial-number="[serial number from google]">
<buyer-billing-address>
...
</buyer-billing-address>
<timestamp>...</timestamp>
<google-order-number>...</google-order-number>
<order-summary>
<total-chargeback-amount currency="GBP">...</total-chargeback-amount>
<google-order-number>...</google-order-number>
<total-charge-amount currency="GBP">...</total-charge-amount>
<total-refund-amount currency="GBP">...</total-refund-amount>
<purchase-date>...</purchase-date>
<archived>false</archived>
<shopping-cart>
<merchant-private-data>
<merchant-note>[the secret about the cart from my system]</merchant-note>
</merchant-private-data>
<items>
</items>
</shopping-cart>
<order-adjustment>
...
</order-adjustment>
<promotions />
<buyer-id>...</buyer-id>
<buyer-marketing-preferences>
<email-allowed>false</email-allowed>
</buyer-marketing-preferences>
<buyer-shipping-address>
...
</buyer-shipping-address>
<order-total currency="GBP">...</order-total>
<fulfillment-order-state>NEW</fulfillment-order-state>
<financial-order-state>REVIEWING</financial-order-state>
</order-summary>
<shopping-cart>
<merchant-private-data>
<merchant-note>[the secret about the cart from my system]</merchant-note>
</merchant-private-data>
<items>
</items>
</shopping-cart>
<order-adjustment>
...
</order-adjustment>
<promotions />
<buyer-id>...</buyer-id>
<buyer-marketing-preferences>
<email-allowed>false</email-allowed>
</buyer-marketing-preferences>
<buyer-shipping-address>
...
</buyer-shipping-address>
<order-total currency="GBP">...</order-total>
<fulfillment-order-state>NEW</fulfillment-order-state>
<financial-order-state>REVIEWING</financial-order-state>
</new-order-notification>
I can then use the secret to match the orders up to the details I'd stored in the database previously.