Create Azure EventHub Message in Azure Functions - azure-eventhub

I'm trying to do some Proof of Concept with EventHub and Azure Functions. I have a Generic Webhook Function in C# that I want to pass a message to my EventHub.
I get stuck on the parameter name given on the "Integrate" tab. If I declare that name among the parameters I have to give it a type. I can't figure out what kind of type though... I've tried:
String (other functions uses that together with the direction, not applicable with webhooks).
EventData
IEnumerable
I can't get it to work. If I don't do this I get the error message:
"Missing binding argument named 'outputEventHubMessage'"
If I give it the wrong type I get the message:
"Error indexing method 'Functions.GenericWebhookCSharp1'. Microsoft.Azure.WebJobs.Host: Can't bind to parameter."
I'm probably a bit lost in documentation or just a bit tired, but I'd appreciate any help here!
/Joakim

Likely you're just missing the out keyword on your parameter. Below is a working WebHook function that declares an out string message parameter that is mapped to the EventHub output, and writes an EventHub message via message = "Test Message".
Because async functions can't return out parameters, I made this function synchronous (returning an object rather than Task<object>). If you want to remain async, rather than use an out parameter, you can instead bind to an IAsyncCollector<string> parameter. You can then enqueue one or more messages by calling the AddAsync method on the collector.
More details on the EventHub binding and the types it supports can be found here. Note that the other bindings follow the same general patterns.
#r "Newtonsoft.Json"
using System;
using System.Net;
using Newtonsoft.Json;
public static object Run(HttpRequestMessage req, out string message, TraceWriter log)
{
string jsonContent = req.Content.ReadAsStringAsync().Result;
dynamic data = JsonConvert.DeserializeObject(jsonContent);
log.Info($"Webhook was triggered! Name = {data.first}");
message = "Test Message";
var res = req.CreateResponse(HttpStatusCode.OK, new {
greeting = $"Hello {data.first} {data.last}!"
});
return res;
}

Related

Akka get response as ComletedStage from actor

I am referring to api
Patters.ask(actor, msg, duration);
here is sample
class MyActor extends AbstractBehavior{
interface Command{}
interface SomeMessage implements Command{ INSTANCE}
public Reveive<Comamnd> receive(){
return newReceiveBuilder().onMessage(SomeMessage.class, this::someMessage).build();
}
private Behavior<Command> someMessage(SomeMessage ref){
System.out.println("Dru lalal");
}
}
ActorRef<MyActor.Command> myActor = ...;
Future<Object> future = Patterns.ask(myActor, SomeMessage.INSTANCE, Duration.ofMillis(10000));
What is gone be object ?
Obviously this won't compile. Some part of picture is missing, but javadoc doesn't state what.
Call "Patterns.ask" suppose to return future with object, those value is provided by actor as business logic. But there is not business logic in actor. I assume there is suppose to be some kind of convention or mapping for method that returns value with what "Patters.ask" triggers.
Same is true about back logic. I will not able to define receiver since it expect to return Receiver not SomeObject and thus, api want't let me bind result to some message. Only thing I can do is manually pass ComputableFuture
ComputableFuture<MyOBject> future = new ComputableFuture<>();
myActor.tell(new Message(future));
private Behavior<Command> someMessage(Message message){
var result = compute();
message.future.comlete(result);
}
And here we go, I have manually manage everything, also issues with passing non serializable message, lifecycle of objects and so on.
Wrong objects is used. Instead of "AskPattern.ask" for new java typed dsl, I used classic "Patterns.ask".
Most of times new api objects has same object name but located in different package. I used to check only package name becouse while playing with in IDE they always next to each other since name is the same. I got used to ignore the classic "com.akka" objects while playing with api.
And here I got into trap, object name is different and not placed in IDE next to "classic" package object.

Using ServiceBusTrigger in the Webjobs SDK 3.x, can the Singleton attribute use a UserProperty as the scope?

I am using a ServiceBusTrigger to execute code when receiving a message. I would like to use the Singleton attribute to limit which messages can be executed in parallel. This attribute allows specifying a scope bound to properties on the incoming message, such that messages with different values can be executed in parallel but ones with the same value must be done serially.
This works when using top level properties on the incoming message object like CorrelationId.
Example
[Singleton("{CorrelationId}", SingletonScope.Function, Mode = SingletonMode.Function)]
public async Task HandleMessage(
[ServiceBusTrigger("my-topic-name", "my-subscription-name"), ServiceBusAccount("my-account-name")]
Message message,
CancellationToken cancellationToken
)
{
await Task.Yield();
}
What I am struggling to figure out is how to achieve the same behavior with user properties on the message. These are stored in the UserProperties dictionary on the Message object. I'm not seeing a way to refer to these with the binding statement in the Singleton attribute, but it seems like this would be a very common use case when combining Singleton with ServiceBusTrigger
The Service Bus Bindings exposes Message Metadata in binding expressions. So, userProperties.<key> should do the trick.

Scala: Get URL Parameters

I'm writing my first Scala lambda, and I have run into a bit of an issue, which i think should be straightforward, but I'm having trouble finding the answer.
So I have the following code that will allow me to accept json and use it in the lambda.
--eventTest.scala
val stream : InputStream = getClass.getResourceAsStream("/test_data/body.json")
--request handler
def handleRequest(input: InputStream): Unit = {
val name = scalaMapper.readValue(input, classOf[NameInfo])
val result = s"Hello there, ${name.firstName} ${name.lastName}."
println(result)
}
This works just fine, but I'm having problems figuring out how to be able to get URL parameters. Does it automatically use the same input Stream? There is seems to be very little documentation on this in Scala.
Thanks
A Lambda function's event is a JSON object. The Lambda runtime will introspect the handler function and attempt to extract or convert that object based on the function signature. I believe the easiest representation is a java.util.Map[String,String] (iirc, Lambda doesn't have a Scala runtime, so you'll have to use Java classes and convert them).
An example event from the API Gateway proxy integration: https://github.com/awsdocs/aws-lambda-developer-guide/blob/master/sample-apps/nodejs-apig/event.json
For more information about the Java runtime: https://docs.aws.amazon.com/lambda/latest/dg/java-handler.html

Is there a way to programmatically invoke a WebJob function from another function within the WebJob and still have the output binding work?

Here's the code:
[return: Table("AnalysisDataTable", Connection = "TableStorageConnection")]
public static async Task<OrchestrationManagerAnalysisData> InputQueueTriggerHandler(
[QueueTrigger("DtOrchestrnRequestQueueName",
Connection = "StorageQueueConnection")] string queueMsg,
[OrchestrationClient] DurableOrchestrationClient client, ILogger logger)
{
logger.LogInformation($"***DtOrchestrationRequestQueueTriggerHandler(): queueMsg = {queueMsg}");
await ProcessInputMessage(queueMsg, client, logger);
// Below is where the code goes to format the TableStorage Entity called analysisData.
// This return causes the above output binding to be executed, saving analysis data to
// Table Storage.
return analysisData;
}
The above code works fine and saves analysisData to TableStorage.
However when I put the output binding attribute on ProcessInputMessage() which is programatically invoked
rather that invoked as a result of a trigger everything works OK except there is no data output
to Table Storage.
[return: Table("AnalysisDataTable", Connection = "TableStorageConnectionName")]
public static async Task<OrchestrationManagerAnalysisData>
ProcessInputMessage(string queueMsg, DurableOrchestrationClient client, ILogger logger)
{
// Do the processing of the input message.
// Below is where the code goes to format the TableStorage Entity called analysisData.
// This return causes the above output binding to be executed, saving analysis data to
// Table Storage.
return analysisData;
}
QUESTION is there a way to cause an output binding to "trigger" when invoked programatically from another function within the WebJob?
I like the labor saving characteristics of output bindings and want to leverage them as much as possible, while also having well factored code, i.e. tight cohesion in each method.
Thanks,
George
is there a way to cause an output binding to "trigger" when invoked programatically from another function within the WebJob?
In short, No.
You send data by using the return value of the function which apply the output binding attribute in function. So, if you want to invoke another function and write data into Table Storage.
If you want to achieve the idea you want, you need to overwrite the return method. However, it is a package integration method, so I suggest that you could use the TableOperation object that inserts the customer entity to the Table Storage.
TableOperation insertOperation = TableOperation.Insert(customer1);
// Execute the insert operation.
table.Execute(insertOperation);
For more details, you could refer to this article.

IBMIOTF/BlueMix Publish Command Syntax

I am attempting to assemble a small proof of concept system on IBM's Bluemix/Internet of Things. Currently this comprises of a Raspberry Pi feeding events up to the cloudbased app, which currently stores those events away, and periodically attempts to send down a command, using the following code block:
def sendCmd(command, payload, device="raspberrypi" ):
deviceId = #Fixed value
global cmdCount
client.publishCommand("raspberrypi", deviceId, str(command), "json", payload)
print "Sending '%s' cmd, payload '%s' to device %s" % (command, payload, deviceId)
cmdCount = cmdCount + 1
As far as the documentation is concerned this appears to be the correct syntax, as described by the documentation :
client.connect()
commandData={'rebootDelay' : 50}
client.publishCommand(myDeviceType, myDeviceId, "reboot", "json", myData)
No exceptions are thrown in this block of code, however the device is not receiving any commands; and the cloud foundry log is not throwing any errors. Is there a subtle point about the syntax I am missing?
This issue boiled down to having instantiated the wrong class on the Raspberry Pi. I had an instance of ibmiotf.application which registered a function to the variable self.client.commandCallback. However nothing appeared to be triggering the callback.
Once I instantiated the device with the ibmiotf.device import rather than ibmiotf.application, the command callback started to be called. This required a couple of the minor changes, to support slightly different function calls, but they were fairly self explanatory when trying to run the code.
The Device Class controls Events being published from the unit, and determines how to handle commands from upstream. Whereas the Application Class handles the receipt of Events and emission of Commands.