Gremlin.NET: Execute queries using .Next() raises NullReferenceException - c#

Starting from the Azure Cosmos DB Graph API example:
https://github.com/Azure-Samples/azure-cosmos-db-graph-gremlindotnet-getting-started
I am interested in using Gremlin.NET (the example uses version 3.2.7) to execute queries using the C# classes instead of writing string queries and execute them using the gremlinClient.SubmitAsync<dynamic>("...") method.
But when I execute the following code I'm getting a
NullReferenceException at Gremlin.Net.Driver.Connection.d__14`1.MoveNext()
when calling .Next()
var gremlinServer = new GremlinServer(hostname, port, enableSsl: true,
username: "/dbs/" + database + "/colls/" + collection,
password: authKey);
var graph = new Graph();
var g = graph.Traversal().WithRemote(new DriverRemoteConnection(new GremlinClient(gremlinServer)));
var vertex = g.V().HasLabel("person").Next();
Console.WriteLine(vertex);
Unfortunately I haven't found any documentation on how to use Gremlin.NET it would be nice if someone of you can point me to some "getting started".
Edit:
The query result from the Azure Cosmos DB Data Explorer looks like the following:
[
{
"id": "thomas",
"label": "person",
"type": "vertex",
"properties": {
"firstName": [
{
"id": "9015b584-375f-4005-af00-f49d6e2d6b94",
"value": "Thomas"
}
],
"age": [
{
"id": "c2300d19-12a0-474a-9405-eb89466bcbb3",
"value": 44
}
]
},
"_isRoot": true,
"_isFixedPosition": true
}
]

The reason why this doesn't work with Cosmos DB is simply that Cosmos DB doesn't support Gremlin Bytecode yet which is what is sent to the server when you use the traversal API as you did.
So, your only option currently is to really write the queries as strings and just send those query strings to the server.
Regarding documentation: Gremlin traversals can be written in different languages (see The Gremlin Graph Traversal Machine and Language for more information about Gremlin in general). Therefore the TinkerPop docs also apply to Gremlin.Net and the Gremlin.Net part of the documentation only explains the aspects that are really specific to Gremlin.Net.

Related

Microsoft Graph API - not able to use orderby or filter on createdDateTime for Sites

I want to query Sites using Microsoft Graph API that were created after a certain time. So I created the following filter query:
createdDateTime ge 2023-01-01T00:00:00Z
I also tried:
createdDateTime ge `2023-01-01T00:00:00Z`
Both generated an invalid request error with no details.
I then tried just doing an orderby createdDateTime. This did "work" but it sorted each page, not the whole dataset. So page 2 had items that should have been in page 1 and so on.
Microsoft Graph API seems really crappy. Does anybody know how to achieve this? Any help would be greatly appreciated.
I've never found a way how to use filter on /sites endpoint.
I'm using /search/query endpoint for searching SharePoint sites based on some criterion.
You should be able to specify filter by Created and properties for sorting.
POST https://graph.microsoft.com/v1.0/search/query
{
"requests": [
{
"entityTypes": [
"site"
],
"query": {
"queryString": "Created > 2022-01-01 AND Created < 2022-12-31"
},
"from": 0,
"size": 25,
"sortProperties": [
{
"name": "Created",
"isDescending": "false"
}
]
}
]
}

Exact Permissions\actions needed to List Azure Resources using C# rest API

I am trying to list all resources in a Subscription using Rest API Call.
https://management.azure.com/subscriptions/{SubscriptionID}/resources?api-version=2021-04-01
It works fine when I run it with Built-In RBAC Role Reader Permissions. For security reasons, I wanted to avoid having read access to entire scope of subscription. So, I need to create a Custom Role with specific permissions\actions to list all Resources in a Subscription.
I am trying with below Custom Role but not able to get any response from Rest API call.
{
"properties": {
"roleName": "AzResourceTest",
"description": "To test the exact ACLs needed to get Resources List from a Subscription",
"assignableScopes": [
"/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
],
"permissions": [
{
"actions": [
"Microsoft.Resources/resources/read"
],
"notActions": [],
"dataActions": [],
"notDataActions": []
}
]
}
}
Can someone please suggest what should I use in actions to get resources.
Got it. "Microsoft.Resources/subscriptions/resources/read" is the action for Custom Role to list resources in a subscription

Filtering Event Messages using Microsoft Graph REST API

I would like to query only Event Messages from Outlook Mail using the Microsoft GRAPH API. I could not find any information on this in the documentation for Microsoft Graph.
I have tried the following queries on the Graph Explorers, but none worked. It seems like Microsoft Graph does not support the IsOf (which filters the type of an object) filtering option. However, I have found that this feature is supported and documented for Azure GRAPH API.
https://graph.microsoft.com/v1.0/me/messages?$filter=isof('#microsoft.graph.eventMessage') eq true
https://graph.microsoft.com/v1.0/me/messages?$filter=isof('#microsoft.graph.eventMessage')
Does anyone know if the operation I tried to do is supported by the Microsoft Graph API? If not, is there anything else I can do to query only Event Messages?
As URL: Query string parameters states for the $filter parameter:
Indicates which entity types should be included in the response. Optional. The supported entity types are: User, Group and Contact. Only valid when resourceSet is “directoryObjects”; otherwise, resourceSet overrides the filter.
For example,
https://graph.windows.net/contoso.com/directoryObjects?api-version=2013-04-05&$filter=isof('Microsoft.WindowsAzure.ActiveDirectory.User')
For Microsoft Graph, I checked Use query parameters, but did not find any samples. Then, I used Graph Explorer to test this scenario as follows:
I assumed that this operation is not supported by Microsoft Graph API for now. You could add your feature request here. Or you could use the $select query parameter to return a set of properties. Details you could follow here.
The isof can be used with objects with an "#odata.type"
E.g. https://graph.microsoft.com/v1.0/deviceManagement/deviceConfigurations?$filter=isof('microsoft.graph.windowsUpdateForBusinessConfiguration')
returns
{
"#odata.context": "https://graph.microsoft.com/v1.0/$metadata#deviceManagement/deviceConfigurations",
"value": [
{
"#odata.type": "#microsoft.graph.windowsUpdateForBusinessConfiguration",
"id": "123123-1234-1234-1234-123456789123",
"lastModifiedDateTime": "2022-07-18T10:01:53.713763Z",
"createdDateTime": "2022-07-18T10:01:53.713763Z",
"description": "",
"displayName": "my Name",
...
{
]
}

SCIM Deserialization Issue in .NET

As a newcomer to the SCIM (System for Cross-domain Identity Management) standard, please excuse any ignorance as I'm on the learning curve trying to figure out how to make clean/simple requests to provision users, delete users and modifiy users.
I'm attempting to use C#/.NET to make HTTP REST requests for a user via SCIM, using the System.Net.Http.HttpClient
https://msdn.microsoft.com/en-us/library/system.net.http.httpclient(v=vs.110).aspx
I can do this successfully and get a JSON response from the server, however in order to easily read the response object and manipulate it, I want to deserialize it.. After much reading around trying to use things like JsonConvert, dynamic etc. I stumbled upon a Microsoft nuget library which seemed to hint at being useful. Sadly there don't appear to be any docs for it*
UPDATED:
One of the authors has updated the nuget page with a link to a blog post which goes some way to explaining usage.
Microsoft.SystemForCrossDomainIdentityManagement
https://www.nuget.org/packages/Microsoft.SystemForCrossDomainIdentityManagement/
The SCIM provider I'm attempting to get data from is Facebook, using the example they publish on their site for getting a user by email:
https://developers.facebook.com/docs/facebook-at-work/provisioning/scim-api#getuserbyemail
Here's a code sample in C# which attempts to get the user from the SCIM service and deserialize them. I'm finding that the queryResponse I get back is deserialized correctly as the properties are populated, however the Core1EnterpriseUser which is the first and only of the resource objects, has null/default properties.
var userName = "foo.bar#foobar.com";
var response = await client.GetAsync($"Users?filter=userName%20eq%20%22{userName}%22");
if (response.IsSuccessStatusCode)
{
var json = await response.Content.ReadAsStringAsync();
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
var userFactory = new QueryResponseJsonDeserializingFactory<Core1EnterpriseUser>();
var queryResponse = userFactory.Create(jsonResponseProperties);
if (queryResponse.TotalResults == 1)
{
var user = queryResponse.Resources.First();
var id = user.Identifier; // this and other properties are null/false etc.
}
}
Here's a sample of the JSON that is returned by the service when I query it:
{
"schemas": [
"urn:scim:schemas:core:1.0"
],
"totalResults": 1,
"itemsPerPage": 10,
"startIndex": 1,
"Resources": [
{
"schemas": [
"urn:scim:schemas:core:1.0",
"urn:scim:schemas:extension:enterprise:1.0",
"urn:scim:schemas:extension:facebook:starttermdates:1.0",
"urn:scim:schemas:extension:facebook:suppressclaimemail:1.0"
],
"id": 180383108978226,
"userName": "foo.bar\u0040foobar.com",
"name": {
"formatted": "Foo Bar",
"familyName": "Bar",
"givenName": "Foo"
},
"title": "Vice President",
"active": true,
"emails": [
{
"primary": false,
"type": "work",
"value": "foo.bar\u0040foobar.com"
}
],
"urn:scim:schemas:extension:enterprise:1.0": {
"department": "IT"
},
"urn:scim:schemas:extension:facebook:starttermdates:1.0": {
"startDate": 0,
"termDate": 0
}
}
]
}
UPDATE:
I'm in dialog with one of the authors of the project and he kindly pointed me at this blog post:
http://blogs.technet.com/b/ad/archive/2015/11/23/azure-ad-helping-you-adding-scim-support-to-your-applications.aspx
He has also updated the nuget library which now includes support for v1 of SCIM, also pointing out that as the JSON data suggests the version used by Facebook is v1: "urn:scim:schemas:core:1.0" so now I can use Core1 rather than attempting to use Core2 classes (I've updated the question above to use Core1EnterpriseUser).
I'm still not able to get my response deserialized correcty at present and will update the question with more information as I have it.
Again, I don't have to use this library if it becomes apparent that it's not easily going to work, as I know the brief description on nuget suggests it was created for Azure AD.
However I'd appreciate any advice on how this type of thing could/should be done as I'm sure there must be a lot of people out there using SCIM - how do you parse your responses/generate your requests such that you have actual objects? Can you automatically parse responses for schemas in order to augment the object with the correct properties?
I was up late last night hand crafting some model classes to handle the response objects - which I do seem to have working. If I can't get the nuget library working (the preferred option) then I'll have to go with my own. :/
Thanks again
peteski
Although I'm still none the wiser about best practices with SCIM, I've managed to get the code working now - with massive thanks to one of the nuget library's authors Craig McMurtry at Microsoft!
There were a few things to iron out along the way, such as the nuget package being updated to include the previous support for older v1 SCIM objects. But here's a snippet of what worked based on the example in my question, but it turned out to be using the Newtonsoft serializer. :(
In the code above the line:
var jsonResponseProperties = await Task.Factory.StartNew(() => { return JsonConvert.DeserializeObject<Dictionary<string, object>>(json); });
Was replaced with:
var jsonResponseProperties = new JavaScriptSerializer().Deserialize<Dictionary<string, object>>(json);
Et voilà! My object's properties are now deserializing...

PayPal Rest API - Update Billing Plan Return URL

I have been using the PayPal Rest API and have successfully created and activated a BillingPlan but I'm having trouble updating said plan's return_url. I think it's something to do with the JSON path I'm using although I'm not sure why!?
Anyway, I am calling the update plan method: https://developer.paypal.com/docs/api/#update-a-plan
A BillingPlan follows the format:
{
"id": "P-94458432VR012762KRWBZEUA",
"state": "ACTIVE",
"name": "T-Shirt of the Month Club Plan",
"description": "Template creation.",
"type": "FIXED",
...
"merchant_preferences": {
"setup_fee": {
"currency": "USD",
"value": "1"
},
"max_fail_attempts": "0",
"return_url": "http://example.com",
"cancel_url": "http://example.com",
"auto_bill_amount": "YES",
"initial_fail_amount_action": "CONTINUE"
},
...
}
I'm using the C# SDK but my request JSON should look very much like:
{
"path": "merchant_preferences",
"value": {
"return_url": "http://example.com/payment/return"
},
"op": "replace"
}
I keep getting responses along the line's of:
{"name":"BUSINESS_VALIDATION_ERROR","details":[{"field":"validation_error","issue":"Invalid
Path provided."}],"message":"Validation
Error.","information_link":"https://developer.paypal.com/webapps/developer/docs/api/#BUSINESS_VALIDATION_ERROR","debug_id":"2ae68f9f0aa72"}
To sum up - I want to change the billing plan return_url from http://example.com to http://example.com/payment/return.
I've changed the path to various things to no avail. Can anyone help??
You cannot update the plan, once it is set to active. The reason for that restriction is that because there could be possible agreements based on that plan, modifying it would affect the already agreed billing agreements.
However, I agree with your problem statement, that changing the Return URL should not be an issue as this is not a part of agreement, but more of a configuration change. It would be nice to somehow allow updating similar settings in Plan, even after active. I will let the API team know about that.
however, in the mean time, there is no way you would be able to do that. Alternatively, you could possibly create a new plan, and use that instead. Not the answer you are looking for, but a probable solution.

Categories