Copy link to clipboard
Copied
I'm adding service bus integration using the azureservicebus package in ColdFusion 2023 update 16. I can send messages to a queue but I haven't been able to schedule a message for later processing. I've followed the documentation here https://helpx.adobe.com/coldfusion/using/integrate-coldfusion-azure-service-bus.html
I've copied the code sample from "Schedule a message" but I get an error every time: "coldfusion.runtime.java.MethodSelectionException: The scheduleMessageToQueue method was not found." Does this method exist in ColdFusion 2023?
Here's my simple example:
<cfscript>
credentialAlias = "AzureServiceBusCredential";
configAlias = "AzureServiceBusConfiguration";
sb = getCloudService(credentialAlias, configAlias);
testQueue = sb.createQueue("testQueue");
sendMessage = {
messageBody = "This is a test message",
messageProperties = {
contentType = "text/plain",
subject = "Test Message",
correlationId = createUUID()
}
}
// This works
sendResponse = testQueue.sendMessage(sendMessage);
myQueue = sb.createQueue("q_006");
schedMessage = {
"messageId" = "001",
"messageBody" = "message body",
"ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
}
try {
// this errors with "The scheduleMessageToQueue method was not found."
scheduleResponse = sb.scheduleMessageToQueue(myQueue, schedMessage)
} catch (any e) {
writeLog(file = "azureErrors", text = e, type="Error");
}
</cfscript>
Copy link to clipboard
Copied
Lisa, while I've never used the ASB feature, and I'm reading this on my phone, I might still be able to offer a useful suggestion. And although your code looks like it SHOULD work compared to the docs, here are two things to consider.
First, are you running this that you feel you must rely on writelog, because you can't produce output to the screen? Can you arrange to call it in such a way that you can? If so, it will simply make diagnosing things easier.
For example, what do you see if you writedump(sb)? That will list all the methods of that cfc instance, including their arguments. Indeed, then dump also your myqueue and schedmessage vars. Despite what our eyes tell us from your code, those may hold something that's somehow unexpected.
Finally, there may also be more useful detail in the error than what your writelog is reflecting. How about dumping the e var within the catch?
Or (sometimes better still) remove the try/catch and just let the normal cf error dump to screen. Another benefit of that is you may see more detail in cf's exception.log (which may not be written to when you catch an error).
Of course, you can also tell writedump/cfdump to write its output to a file instead of the screen, if you must for some reason.
Let us know what you find, or better if you may be able to use that info to resolve the problem on your own. Or maybe someone else will see a different solution for you.
Copy link to clipboard
Copied
@lisar36119501 , I suspect that the cause of the error is myQueue. In your code, it is passed as a string argument. I can understand why. That is what ColdFusion's Azure Service Bus documentation suggests.
However, it is unlikely for myQueue to be a string. My reasoning follows.
ColdFusion's Azure Service Bus documentation contains examples such as
tempQ = sb.createQueue("Queue18")
//writedump(tempQ)
mypath=tempQ.getPath()
which suggest that createQueue() returns a complex object. In addition, the documentation says that the syntax for scheduleMessageToQueue is:
scheduleMessageToQueue(String queuePath, Map metadata)
In your code, schedMessage is a struct, hence of type CaseInsensitiveMap. That's fine. But myQueue is probably not a string. As I have shown, myQueue is a complex object which has the queue-path as one of its attributes. Hence the following suggestions.
myQueue = sb.createQueue("q_006");
schedMessage = {
"messageId" = "001",
"messageBody" = "message body",
"ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
};
try {
scheduleResponse = sb.scheduleMessageToQueue(myQueue.getPath(), schedMessage);
} catch (any e) {
writeLog(file = "azureErrors", text = e, type="Error");
}
/**
Look for ways to obtain the queue-path from
the information in the metadata or the queue object.
**/
myQueue = sb.createQueue("q_006");
writedump(var="#getMetadata(myQueue)#", label="GetMetadata(myQueue)");
writedump(var="#myQueue#", label="myQueue");
/* What do the dumps tell you? Here I have assumed the dumps say the path is myQueue.name */
myQueuePath = myQueue.name;
schedMessage = {
"messageId" = "001",
"messageBody" = "message body",
"ScheduledEnqueueTimeUtc" = dateAdd("n", 10, now())
}
try {
// this errors with "The scheduleMessageToQueue method was not found."
scheduleResponse = sb.scheduleMessageToQueue(myQueuePath, schedMessage)
} catch (any e) {
writeLog(file = "azureErrors", text = e, type="Error");
}
Copy link to clipboard
Copied
Thank you Charlie and BKBK for your advice. I did some dumping and determined that yes, despite the documentation having the example of
scheduleResponse = sb.scheduleMessageToQueue(myQueue, schedMessage)
where myQueue is an object, the method does actually expect the string queue name.
Changing the code to
scheduleResponse = sb.scheduleMessageToQueue("Q_006", schedMessage)
gets me past the error of "scheduleMessageToQueue method was not found".
Now I get "Unknown Field : ScheduledEnqueueTimeUtc".
I thought maybe the format of the time was the issue, even though the doc example had "02/02/2020", so I dug into the Azure documentation and found it was expecting a DateTimeOffset: an ISO8601 datetime.
So, changing the parameter to be the string queue name, and formatting the send time as ISO8601:
schedMessage5 = {
"messageId" = "005",
"messageBody" = "message body",
"ScheduledEnqueueTimeUtc" = dateTimeFormat(dateAdd("n", 10, now()), "iso")
}
try {
scheduleResponse = sb.scheduleMessageToQueue("Q_006", schedMessage5);
} catch (any e) {
writeDump(e);
}
I get this error instead
struct
Message | Unknown Field : ScheduledEnqueueTimeUtc | ||||||||||||||
StackTrace | coldfusion.cloud.validator.FieldValidationFailedException: Unknown Field : ScheduledEnqueueTimeUtc at coldfusion.cloud.util.ValidatorFiller.fillObject(ValidatorFiller.java:70) at coldfusion.cloud.util.ValidatorFiller.fillObject(ValidatorFiller.java:48) at coldfusion.cloud.azure.servicebus.ServiceBusClientImpl.scheduleMessage(ServiceBusClientImpl.java:456) at coldfusion.cloud.azure.servicebus.ServiceBusClientImpl.scheduleMessageToQueue(ServiceBusClientImpl.java:430) at jdk.internal.reflect.GeneratedMethodAccessor158.invoke(Unknown Source) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at coldfusion.runtime.StructBean.invoke(StructBean.java:509) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4248) at coldfusion.runtime.CfJspPage._invoke(CfJspPage.java:4100) at cfbasicServiceBusTester2ecfm1289919878.runPage(/Users/lisarees/Documents/repos/mainsite/basicServiceBusTester.cfm:120) at coldfusion.runtime.CfJspPage.invoke(CfJspPage.java:251) at coldfusion.tagext.lang.IncludeTag.handlePageInvoke(IncludeTag.java:749) at coldfusion.tagext.lang.IncludeTag.doStartTag(IncludeTag.java:578) at coldfusion.filter.CfincludeFilter.invoke(CfincludeFilter.java:65) at coldfusion.filter.ApplicationFilter.invoke(ApplicationFilter.java:573) at coldfusion.filter.RequestMonitorFilter.invoke(RequestMonitorFilter.java:43) at coldfusion.filter.MonitoringFilter.invoke(MonitoringFilter.java:40) at coldfusion.filter.PathFilter.invoke(PathFilter.java:162) at coldfusion.filter.IpFilter.invoke(IpFilter.java:45) at coldfusion.filter.LicenseFilter.invoke(LicenseFilter.java:30) at coldfusion.filter.ExceptionFilter.invoke(ExceptionFilter.java:97) at coldfusion.filter.ClientScopePersistenceFilter.invoke(ClientScopePersistenceFilter.java:28) at coldfusion.filter.BrowserFilter.invoke(BrowserFilter.java:38) at coldfusion.filter.NoCacheFilter.invoke(NoCacheFilter.java:60) at coldfusion.filter.GlobalsFilter.invoke(GlobalsFilter.java:38) at coldfusion.filter.DatasourceFilter.invoke(DatasourceFilter.java:22) at coldfusion.filter.CachingFilter.invoke(CachingFilter.java:62) at coldfusion.CfmServlet.service(CfmServlet.java:231) at coldfusion.bootstrap.BootstrapServlet.service(BootstrapServlet.java:311) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:199) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at coldfusion.monitor.event.MonitoringServletFilter.doFilter(MonitoringServletFilter.java:46) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at coldfusion.inspect.weinre.MobileDeviceDomInspectionFilter.doFilter(MobileDeviceDomInspectionFilter.java:57) at coldfusion.bootstrap.BootstrapFilter.doFilter(BootstrapFilter.java:47) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:168) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:144) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:168) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:130) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:359) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:397) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:935) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1826) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1189) at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:658) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63) at java.base/java.lang.Thread.run(Thread.java:842) | ||||||||||||||
Suppressed | array[empty] | ||||||||||||||
TagContext | array
| ||||||||||||||
Type | coldfusion.cloud.validator.FieldValidationFailedException |
And since dumping the queue object showed a similar method
scheduleMessage(java.util.Map)
I tried calling that method with an ISO8601 also
scheduleResponse = myQueue.scheduleMessage(schedMessage5);
But got the same error message about "Unknown Field : ScheduledEnqueueTimeUtc"
Luckily I don't actually need the scheduled message functionality, but maybe my exploration of it will be helpful to someone else.
Copy link to clipboard
Copied
@lisar36119501 , thanks for trying out the suggestions and for the update.
I can tell you that the cause of the error
Unknown Field : ScheduledEnqueueTimeUtc
is the same as the cause of your original error:
In this case, the documentation makes an error in suggesting that ScheduledEnqueueTimeUtc is one of the standard keys of the Map object representing the message to be queued. It is not. So, remove it from the message struct.
You can add the Scheduled Enqueue UTC Time only through the API itself. Internally, ColdFusion’s getCloudService() abstraction wraps Java's Azure Service Bus SDK (Software Development Kit).
So you have to do something like this, for example
/*
Here, create a date-time in UTC, complete with offset.
Suppose it is called 'scheduledTimeUtc'
*/
// Set the scheduled enqueue time (UTC)
message.setScheduledEnqueueTime(scheduledTimeUtc);
Copy link to clipboard
Copied
Bug reported: https://tracker.adobe.com/#/view/CF-4228164
Copy link to clipboard
Copied
I tried to upvote this comment but clicking Upvote or the arrow doesn't appear to be doing anything and there are no errors in my browser console, so consider this my upvote. 👍
Copy link to clipboard
Copied
Lisa,. I just up voted your comment here. So it is at least working for some. And perhaps it differs per browser or platform (though of course it should not).
Copy link to clipboard
Copied
I just noticed that "Schedule a message" appears twice in the documentation with the same code example. Only in the second listing does it mention the syntax (which contradicts the code example).
It's also worth noting that the code example for "Cancel scheduled message to queue", which I looked at to try to figure out how to schedule the message in the first place, references `qutil` and `scheduler` which I assume were utilities in the codebase of whoever wrote the samples, but don't exist in Coldfusion. This led to more frustration, as you can imagine, since I can't possibly know what those utilities look like or how they interact with the Azure Service Bus apis.
The documentation for ColdFusion's integration with Amazon SNS, by contrast, looks much more complete and helpful. It actually has the apis and endpoints listed!
https://helpx.adobe.com/coldfusion/using/integrate-coldfusion-amazon-sns.html
Copy link to clipboard
Copied
That's certainly lamentable to hear. But I see that the bug bkbk reported above is now marked as fixed. It's not clear what changed. You may well even be seeing a cached version. Can you try from a browser other than what you're using, or try a incognito/private window? Or bkbk do you see what may have changed?
Lisa, it seems these other issues would warrant another bug report. You can file one easily at tracker.adobe.com. Would you be open to doing that, rather than leaving this matter to die on the vine here? It would be a good thing for you to know how to do. Clearly they do attend to them (though no guarantee).
Copy link to clipboard
Copied
The docs have just this morning been updated to reflect the string queue name as a parameter, and they removed the scheScheduledEnqueueTimeUtc from the message, but they didn't say how to schedule the message for a specific time, so that's not as helpful.
Thanks, Charlie, I will try again to file a bug report.
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Thanks, @lisar36119501 . I have voted for both of your tickets.
Find more inspiration, events, and resources on the new Adobe Community
Explore Now