It appears that through all documentation there is very little dedicated to gRPC versioning best practices. Overall what I understood is that things should be kept simple, such as not removing fields or their orders and proceed with evaluating what is the set of fields that are part of the message.
I was planning on simply defining a standard to my messages that includes a version field as the first in order, such as:
message userCreateRequest {
string version = 1
string name = 2;
string lastName = 3;
}
With the above, the version field could be treated to retrieve the right "versioning intention" by clients. As a default it vcould be "v1.0" and from that the service would verify how to handle the expectations.
example v1.0 request:
userCreateRequest {
version: "v1.0",
name = "jim",
lastName = "smith"
}
example v2.0 request:
userCreateRequest {
version: "v2.0",
name = "jim",
lastName = "smith"
}
Question: is this against any guidance or best practice?
The major version number should be part of the proto package, like your.package.v2. This is the recommendation of the Google API design guide (which is targeted to gRPC services also providing REST). Because the version is part of the package name, each major version is considered a separate service.
If the major version number is 1, then while it may not be essential to have the version number in the package name, it is still a good idea to reduce confusion.
Related
I am currently trying to populate a wikidata instance via POST requests. For this purpose I use the requests library in Python together with the MediaWiki API.
So far I managed to create claims with different datatypes (like String, Quantity, Wikidata items, Media ...). The general scheme I use is this (with different value strings for each datatype):
import requests
session = requests.Session()
# authenticate and obtain a csrf_token
parameters = {
'action': 'wbcreateclaim',
'format': 'json',
'entity': 'Q1234',
'snaktype': 'value',
'property': 'P12',
'value': '{"time": "+2022-02-19T00:00:00Z", "timezone": 0, "precision": 11, "calendarmodel": "http://www.wikidata.org/entity/Q1985727"}',
'token': csrf_token,
'bot': 1,
}
r = session.post(api_url, data=parameters)
print(r.json())
Every attempt to insert data of type time leads to an invalid-snak error (info: "invalid snak data.").
The following changes did not solve the problem:
submitting the value string as dictionary value (without the single quotes),
putting the numeric values into (double) quotes,
using a local item for the calendarmodel ("http://localhost:8181/entity/Q73"),
adding before and after keys in the dictionary,
omitting timezone, precision, calendarmodel and combinations thereof,
formatting the time string as 2022-02-19,
submitting the request with administrator rights (though the error message does not
suggest a problem with insufficient user rights).
Do you know, what I'm doing wrong here? What must the value field look like?
I am aware of the fact that special libraries or interfaces for exist for these tasks. But I do want to use the Wikidata API directly with the requests library in Python.
Thank you very much for your help!
Installed software versions:
MediaWiki: 1.36.3
PHP: 7.4.27
MariaDB 10.3.32-MariaDB-1:10.3.32+maria~focal
ICU 67.1
It works if the value string is generated from the dictionary via json.dumps().
I have a simple task which involves creating online meetings using Microsoft Graph API. I'm using the basic sample code from the site, something like this:
var onlineMeeting = new OnlineMeeting
{
StartDateTime = DateTimeOffset.Parse("2019-07-12T21:30:34.2444915+00:00"),
EndDateTime = DateTimeOffset.Parse("2019-07-12T21:30:34.2444915+00:00"),
Subject = "This is the subject"
};
var meeting = await graphClient.Users["userid here"].OnlineMeetings.Request().AddAsync(onlineMeeting);
This unfortunately gives a 400 response with a very obsure reasoning. However, I was able to narrow down the probable cause of the problem: the serialization of the DateTimeOffset properties. For some reason, my requests contain the data in the format like 19/07/12 21:30:34 -07:00", instead of the required format, which is basically the same as the argument provided for DateTimeOffset.Parse().
My question is how can I customize the serialization format in the SDK? And more importantly, why should I do this explicitly, and why can't I find any mention of this in the documentation?
Turns out I have not updated the SDK for a while now and I was using an old version. I updated to the latest version and the problem went away :)
Using the older "Windows.Azure.ServiceBus" library, I am able to setup a SqlFilter that takes as its parameters a TimeSpan, but when I try the same using the "Microsoft.Azure.ServiceBus" library it fails with the following error:
Object is not of supported type: TimeSpan. Only following types are
supported through HTTP: string,int,long,bool,double,DateTime
What I am trying to do:
I want to have 2 subscriptions on my topic (highPriority, normalPriority)
Messages have a user property called "StartDate"
If StartDate <= 1 day, then it should go to highPriority subscription, else it should go to normalPriority. [i.e (StartDate - sys.EnqueuedDateTimeUtc) <= 24 hours].
Code that works (when using the older .net-framework Windows.Azure.ServiceBus package):
SqlFilter highMessagesFilter =
new SqlFilter("(StartDate-sys.EnqueuedTimeUtc) <= #TimeSpanImmediateWindow");
highMessagesFilter.Parameters.Add("#TimeSpanImmediateWindow", TimeSpan.FromDays(1));
var subscription = SubscriptionClient.CreateFromConnectionString(connectionString,topicName, subName1);
subscription.RemoveRule(RuleDescription.DefaultRuleName);
subscription.AddRule(new RuleDescription()
{
Name = RuleDescription.DefaultRuleName,
Filter = highMessagesFilter,
Action = new SqlRuleAction("set priorityCalc = (StartDate-sys.EnqueuedTimeUtc)")
});
Where as, this code (using: Microsoft.Azure.ServiceBus) doesnt work:
var filter = new SqlFilter("(StartDate-sys.EnqueuedTimeUtc) <= #TimeSpanHoursImmediateWindow");
filter.Parameters.Add("#TimeSpanHoursImmediateWindow",TimeSpan.FromDays(1));
var ruleDescription = new RuleDescription
{
Filter = filter,
Action = new SqlRuleAction(#"
SET HighPriority = TRUE;
SET Window = StartDate - sys.EnqueuedTimeUtc
"),
Name = RuleDescription.DefaultRuleName,
};
await managementClient.UpdateRuleAsync(topicPath,subscriptionName,ruleDescription);
The above code throws the following error:
Object is not of supported type: TimeSpan. Only following types are
supported through HTTP: string,int,long,bool,double,DateTime
If instead of managementClient.UpdateRuleAsync, I try using the following code:
var subClient = new SubscriptionClient(connectionString, topicPath, subscriptionName);
await subClient.RemoveRuleAsync(RuleDescription.DefaultRuleName);
await subClient.AddRuleAsync(ruleDescription);
It fails, with the following error (ServiceBusException):
Message The service was unable to process the request; please retry
the operation. For more information on exception types and proper
exception handling, please refer to
http://go.microsoft.com/fwlink/?LinkId=761101
The microsoft link is to a list of exceptions, and FilterException, but its not!
Here is the stack trace of the 2nd exception:
at
Microsoft.Azure.ServiceBus.Amqp.AmqpSubscriptionClient.OnAddRuleAsync(RuleDescription
description) in
C:\source\azure-service-bus-dotnet\src\Microsoft.Azure.ServiceBus\Amqp\AmqpSubscriptionClient.cs:line
132 at
Microsoft.Azure.ServiceBus.SubscriptionClient.AddRuleAsync(RuleDescription
description) in
C:\source\azure-service-bus-dotnet\src\Microsoft.Azure.ServiceBus\SubscriptionClient.cs:line
499 at UserQuery.Main() in
C:\Users\XXXX\AppData\Local\Temp\LINQPad6_quhgasgl\niqvie\LINQPadQuery.cs:line
82
So my questions are:
Can I use TimeSpan parameters using .net standard library? or will I have to use the older .net framework library if I wanted to use TimeSpans.
Is there a better way to implement what I am trying to do, a way that would work with the newer .net standard library? (FYI: I thought about sending the calculation as the parameter (decimal) and then the parameter would be a double, instead of a TimeSpan). And in fact, thats what I might end up doing.
If the library is throwing an exception stating that TimeSpan is not a supported type, then it's pretty much what you have. Note that the .NET Standard client has two implementations, the ManagementClient and some operations via entity clients, such as subscription client. The latter is implemented using AMQP. ManagementClient is entirely based on HTTP. While it would be ideal to use the AMQP implementation, it's incomplete. I would recommend relying on the ManagementClient. This is likely the reason why modifying rules using a subscription client is throwing an exception.
Regarding a better way - your idea sounds right. As long as it's not a type that the new client doesn't accept. Also, you can raise an issue with the library team at https://github.com/Azure/azure-sdk-for-net/issues if you'd like to know the reason why TimeSpan is no longer supported.
I have AWS step machine and one of the step is used to notify failure using SNS service. I want to select some metadata from input json into outgoing message. So i am trying to concatenate constant string with jsonpath like below
"Notify Failure": {
"Type": "Task",
"Resource": "arn:aws:states:::sns:publish",
"Parameters": {
"Message.$": "A job submitted through Step Functions failed for document id $.document_id",
"Subject":"Job failed",
"TopicArn": "arn:aws:sns:us-west-2:xxxxxxx:xxxxxxxx"
},
"End": true
}
where document_id is one of the property in input json
However when i try save state machine defination i get error
There is a problem with your ASL definition, please review it and try
again The value for the field 'Message.$' must be a valid JSONPath
I was able to solve a similar issue using:
"Message.$": "States.Format('A job submitted through Step Functions failed for document id {}', $.document_id)",
Described in a AWS News Blog post.
The JSONPath implementation referenced from the AWS Step Functions documentation supports String concatenation via $.concat($..prop) but sadly this does not work when deployed to AWS, suggesting that AWS uses a different implementation.
Therefore there is no way to do string concatenation with JSONPath in AWS.
As the message suggest you need to provide a valid JSONPath.
"Message.$": "$.document_id"
You cannot use any string interpolation as it invalidates the JSONPath format. You will need to construct the message in the preceding state.
I know that this thread is quite old, but I think it might be useful for some people.
It IS actually possible to concatenate strings or JSONPaths in AWS Step Functions thanks to the function States.Format.
The principle is the same as the string format method in Python.
Example with strings
"States.Format('{}<separator_1>{}<separator_2>{}', 'foo', 'bar', 'baz')"
will give you
'foo<separator_1>bar<separator_2>baz'
Example with JSONPaths
"States.Format('{}<separator>{}', $.param_1, $.param_2)"
will give you
'<value of param_1><separator><value of param_2>'
NB: You can also combine strings with JSONPaths.
Hope it helps!
I have a client in the healthcare space, that might need an IVR system to take patients through a simple six question survey (all of the "press 1 for I Strongly Agree, up to 5 for I Strongly Disagree" type). The factors involved...
Small client: We don't need enterprise-level firepower. We'd expect maybe 50-100 surveys per month.
Hosted: We will be setting up an ASP.NET server with a SQL Server database hosted at a co-location facility. We don't have our own server room and pipes to the internet. I'll want something already hosted that I can tie into. (It needn't be on my ASP.NET server, of course.)
Integration: The rest of their system will be .NET and SQL Server based, so I want to be able to automate pulling the data from the IVR system into my own
Ad-Hoc: We won't be robo-calling. A typical scenario for us: My client receives a live call from a patients...and at the end, will say "Do you have another minute? Can I have you take a phone survey?" If the patient says yes, then either...
they hang up, my client dials a few commands into the IVR system, at the IVR calls the patient...or...
my client doesn't hang up, but transfers the current phone call to the IVR system
Suggestions?
Check out twilio
I believe surveymonkey has an implementation over this API that might also work for you.
I've used Microsoft Speech Server 2007 (Part of Office Communications Server 2007) in the past and it will meet all of your requirements. You can find out more about it here: http://gotspeech.net/
It looks like Speech Server 2007 has been renamed Tellme and you can find out more here: http://www.microsoft.com/en-us/Tellme/developers/default.aspx
I have not used the new Tellme version, but Speech Server 2007 was great. You could implement an entire IVR system within Visual Studio using workflows and .NET code. I would expect Tellme probably makes it even easier.
Ricky from Twilio here.
We put together a C# tutorial for this exact use case I wanted to share:
https://www.twilio.com/docs/tutorials/walkthrough/automated-survey/csharp/mvc
There's a sample configuration that lets you set all the survey questions you want to ask:
protected override void Seed(AutomatedSurveysContext context)
{
context.Surveys.AddOrUpdate(
survey => new { survey.Id, survey.Title },
new Survey { Id = 1, Title = "Twilio" });
context.SaveChanges();
context.Questions.AddOrUpdate(
question => new { question.Body, question.Type, question.SurveyId },
new Question
{
Body = "Hello. Thanks for taking the Twilio Developer Education survey. On a scale of 0 to 9 how would you rate this tutorial?",
Type = QuestionType.Numeric,
SurveyId = 1
},
new Question
{
Body = "On a scale of 0 to 9 how would you rate the design of this tutorial?",
Type = QuestionType.Numeric,
SurveyId = 1
},
new Question
{
Body = "In your own words please describe your feelings about Twilio right now? Press the pound sign when you are finished.",
Type = QuestionType.Voice,
SurveyId = 1
},
new Question
{
Body = "Do you like my voice? Please be honest, I dislike liars.",
Type = QuestionType.YesNo,
SurveyId = 1
});
context.SaveChanges();
}