Transforming JSON template based on JSON values posted into API - c#

I have got a requirement of building an azure function which transforms data in our COSMOS DB based on the value posted by a calling service.
So consider this JSON template
{
"processExecutionId": 1000,
"processId": "$PID",
"parentProcessId": 10,
"objectNameTag": "$ObjectName",
"objectName": "bbps.fx",
"processStartedOn": "$startedOn",
"processCompletedOn": "$CompletedAt",
"processExecutionStatusId": 2,
"configurationPayload": "Actual Config Payload with replaced values by the orchestrator or payload read service",
"objectMetadata": {
"jsonPayLoadRead": {
"messages": "$Message"
},
"writeToDB": "$IsWrite"
}
}
This is something we in COSMOS corresponding to a key.
So when a requester application posts that Key it has a JSON object in its body like this
{
"processStartedOn": "2022-01-25 10:10:32",
"processCompletedOn": "2022-01-25 10:20:25",
"objectMetadata": {
"jsonPayLoadRead": {
"messages": "Data uploaded"
},
"writeToDB": "True"
}
}
So the method posting parameters for the template expecting a response from the API after replacing those variables in the template with the values.
The JSON template is not always the same structure. Otherwise we can atleast define a class and can deserialize into it. So what ever the key posted our service needs to take the corresponding JSON template from COSMOS and do the transformation.
So dont know how to handle it the best way or is there is any way to handle this process within COSMOS itself rather than trying using C#.
Please share your thoughts

You can always add a TemplateType property in your class so that you know the various options you have and based on that you know what class to use, there are also ways to stream from cosmos directly without using classes at all but it depends a little what you are trying to achieve if you just need to hand over to another app or not then you can stream from cosmos without even knowing what the structure is

Related

FHIR Client - How do I create a "valueReference"

I am using the NuGet package Hl7.Fhir.R4 to connect to the NHS ERS API. Part of the "CreateReferral" method requires an extension like this:
"extension": [
{
"url": "https://fhir.nhs.uk/STU3/StructureDefinition/Extension-eRS-Shortlist-SearchCriteria-1",
"valueReference": {
"reference": "#ServiceSearchCriteria-1"
}
}
]
I can't seem to find a model class that will create this output. Any ideas?
You should be able to add an extension to an element/resource with the AddExtension method. As parameters, you fill in the extension's url and a value of any FHIR datatype. For your extension, that would be a Reference, which is modelled by the ResourceReference class:
element.AddExtension("https://fhir.nhs.uk/STU3/StructureDefinition/Extension-eRS-Shortlist-SearchCriteria-1",
new ResourceReference("#ServiceSearchCriteria-1"));
When looking at the referral API, it seems to use FHIR STU3, so you may need to change your library to Hl7.Fhir.Stu3 as well to avoid mismatches in the resource's fields and other version differences. The above method should still work for adding your extension though.

How to make startup Azure Function

I have a Azure Function like that
[FunctionName("Function1")]
public static void Run([ServiceBusTrigger("myqueue", AccessRights.Manage, Connection = "AzureWebJobsServiceBus")]string myQueueItem, TraceWriter log)
{
log.Info($"C# ServiceBus queue trigger function processed message: {myQueueItem}");
}
I want to dynamic bind myqueue and AzureWebJobServiceBus connection string in a startup or OnInit of app without as method's parameter above. I mean, I want to a method run first of all like Program.cs in WebJob to binding or start up global variables. Can I do that in Azure Function and how to do it?
Many thanks
The attributes here are compiled into a function.jsonfile before deployment that has the info on what the binding talks to. Often things like the connection string reference app settings. Neither of these can be modified within the code itself (so a Program.cs couldn’t modify the function.json binding).
Can you share any more on your scenario? If you have multiple queues you want to listen to could you deploy a function per queue? Given the serverless nature of Functions there isn’t a downside to having extra functions deployed. Let me know - happy to see if we can help with what you need.
Edit
The suggestion below doesn't work for a Trigger, only for a Binding.
We have to wait for the team to support Key Vault endpoints in Azure Functions, see this GitHub issue.
I think what you are looking for is something called Imperative Bindings.
I've discovered them myself just yesterday and had a question about them also. With these type of bindings you can just dynamically set up the bindings you want, so you can retrieve data from somewhere else (like a global variable, or some initialization code) and use it in the binding.
The thing I have used it for is retrieving some values from Azure Key Vault, but you can also retrieve data from somewhere else of course. Some sample code.
// Retrieving the secret from Azure Key Vault via a helper class
var connectionString = await secret.Get("CosmosConnectionStringSecret");
// Setting the AppSetting run-time with the secret value, because the Binder needs it
ConfigurationManager.AppSettings["CosmosConnectionString"] = connectionString;
// Creating an output binding
var output = await binder.BindAsync<IAsyncCollector<MinifiedUrl>>(new DocumentDBAttribute("TablesDB", "minified-urls")
{
CreateIfNotExists = true,
// Specify the AppSetting key which contains the actual connection string information
ConnectionStringSetting = "CosmosConnectionString",
});
// Create the MinifiedUrl object
var create = new CreateUrlHandler();
var minifiedUrl = create.Execute(data);
// Adding the newly created object to Cosmos DB
await output.AddAsync(minifiedUrl);
There are also some other attributes you can use with imperative binding, I'm sure you'll see this in the docs (first link).
Instead of using Imperative Bindings, you can also use your application settings.
As a best practice, secrets and connection strings should be managed using app settings, rather than configuration files. This limits access to these secrets and makes it safe to store function.json in a public source control repository.
App settings are also useful whenever you want to change configuration based on the environment. For example, in a test environment, you may want to monitor a different queue or blob storage container.
App settings are resolved whenever a value is enclosed in percent signs, such as %MyAppSetting%. Note that the connection property of triggers and bindings is a special case and automatically resolves values as app settings.
The following example is an Azure Queue Storage trigger that uses an app setting %input-queue-name% to define the queue to trigger on.
{
"bindings": [
{
"name": "order",
"type": "queueTrigger",
"direction": "in",
"queueName": "%input-queue-name%",
"connection": "MY_STORAGE_ACCT_APP_SETTING"
}
]
}

Unspecified type of the property when deserializing an object

I am trying to use OneSignal API. My problem isn't specific to OneSignal but I think that referencing it might make it easier to explain.
OneSignal is an SAAS for delivering notifications to phones and browsers and I am trying to hook it up to my server. The problem is that the request to OneSignal API returns:
{
"id": "458dcec4-cf53-11e3-add2-000c2940e62c",
"recipients": 5
}
or
{
"errors": {
"invalid_player_ids" : ["5fdc92b2-3b2a-11e5-ac13-8fdccfe4d986", "00cb73f8-5815-11e5-ba69-f75522da5528"]
}
}
or
{
"id": "",
"recipients": 0,
"errors": ["All included players are not subscribed"]
}
while I am trying to deserialize the request using DataContracts and DataContractJsonSerializer.
My question is: how do I parse a JSON where a property can be empty, can be an object or an array of strings? Is there a way to do that using just standard DataContract attributes or do I have to write my own serializer? If so, could you point me to some resources or to any tutorial since I couldn't find anything resolving my problem so far?

Pass a CSV as entry parameter in a REST API

I have to develop a method in a REST API which will be called every hour. I have some methods with internal objects and I have not any problem. But this new method the entry parameter will be a CSV file. Which type have I declare for this parameter? I have tried some types but I can't find the properly type..
For example, I have another method like this:
[ActionName("RetrieveBookingList")]
[HttpPost]
public ListRS RetrieveBookingList(ListRQ rq)
{
return MessageRetrieveBookingList.Execute(rq);
}
And someone can help me to how can send it (header, raw data (file attached?)) via POSTMAN or via SOAP UI in rest project to debug?
Many thanks.

JSON to Knockout serializer on server

I am using Web API in a current project. It returns a json string which is than converted to a knockout-observable by using the knockout-mapping plugin. I am wondering if this could not be done before, on the server side. For example:
Now a GET call to \Product returns the following:
{ Id: 2, Name: "Apple", Categories: ["fruit"] }
What I like to have directly returned by the server:
var data={
Id: ko.observable(2),
Name: ko.observable("Apple"),
Categories: ko.observableArray([
ko.observable("fruit")
])
};
Is there any .NET lib to do this? Or is there any way to extend the JSON.NET lib?
Although you could use an OData formatter, it could get difficult to maintain if your front end changes. You could essentially do the same thing on your front end by creating a viewmodel from your server's JSON:
function ViewModel(data)
{
this.Id = ko.observable(data.Id);
this.Name = ko.observable(data.Name);
this.Categories = ko.observableArray(data.Categories);
}
This way, as pointed out by Shane, you wouldn't have your back end tightly coupled with Knockout. Also, as a little side note to your categories, I wouldn't recommend setting each individual item in your array to an observable unless you need to observe each item.

Categories

Resources