How to get the Azure Cosmos DB Request Units after each operation in Entity Framework - azure

I can see in the logs/traces the Entity Framework Cosmos DB provider displays the request units after each operation. Is there an easy way to get to that RU number programmatically? Can be pretty useful in integration, and benchmark tests, CI/CD gates, etc. It should be easy, right? It is in the header of the response to the HttpClient.

This might not be the easiest method possibly, but with the lack of other responses I thought it was worth mentioning.
You could add a custom HttpClientFactory using the CosmosDbContextOptionsBuilder class. Then let your factory yield you an instance of an HttpClient with a custom DelegatingHandler. In the handler you can override the SendAsync and obtain the response which should include the RU charge in the headers if applicable.

You can get the Request Units consumed in Azure Cosmos DB for each operation via response object programmatically.
// for read requests
double requestUnits = readResponse.RequestCharge;
// for query
double requestUnits = feadResponse.RequestCharge;
Please go through the object model. There are similar API's in other language SDK's as well.
https://learn.microsoft.com/dotnet/api/microsoft.azure.cosmos.response-1?view=azure-dotnet

Related

OpenAPI Generator issue with Destination service API specification

I want to get all destinations on subaccount and instance level. In SAP API business Hub, I found the API information and "SAP Cloud SDK" tab to generate code by OpenAPI generator.
https://api.sap.com/api/SAP_CP_CF_Connectivity_Destination/overview
I downloaded the API specification and added dependencies into Cloud SDK for Java project. The code is generated successfully with some errors (unknown models)in generated api classes.
For example in DestinationsOnSubaccountLevelApi.class, model OneOfDestinationNameOnly is imported and used in method but it is not generated in model package.
I looked into API specification and found that there were two types of response entity. That is the reason why the code could not be generated properly. I can modify the API specification to make it work but it should not be the long term solution. Is there any other way to fix this issue?
Unfortunately the SAP Cloud SDK Generator for Open API services is not yet able to understand oneOf relationship that is modeled in the specification.
As an alternative, would you consider using the DestinationAccessor API for resolving single destinations?
You can also directly instantiate an ScpCfDestinationLoader, which allows for querying all destinations:
ScpCfDestinationLoader loader = new ScpCfDestinationLoader();
DestinationOptions options = DestinationOptions
.builder()
.augmentBuilder(ScpCfDestinationOptionsAugmenter.augmenter().retrievalStrategy(ScpCfDestinationRetrievalStrategy.ALWAYS_SUBSCRIBER))
.build();
Try<Iterable<ScpCfDestination>> destinations = loader.tryGetAllDestinations(options);
Similar to the default behavior of DestinationAccessor API, in the code above only the subscriber account will be considered. Other options are:
ScpCfDestinationRetrievalStrategy.ALWAYS_SUBSCRIBER
ScpCfDestinationRetrievalStrategy.ALWAYS_PROVIDER
ScpCfDestinationRetrievalStrategy.SUBSCRIBER_THEN_PROVIDER

Passing OAuth token in multi threaded application

We have a SpringBoot application based on the Sap Cloud SDK (3.32.0) and are using PrincipalPropegation to our on-prem SAP environment.
Our application is also using the Axon Framework (an eventsourcing framework). This means our calls to our RestControllers are send as commands to the Aggregates, which in turn sends out events on the eventbus. Normally we pass the oauth token by adding metadata on the event messages. This is handled by the axon framework. Events are dispatched on different threads then the ones that process the commands.
However, we recently started using the cloud sdk and generated OData V2 clients to send/retrieve information to our on-prem SAP instances. The SAP cloud SDK tries to fetch the AuthToken from the ThreadContext, however, due to the async nature of the Axon framework, this does not work properly.
Is there a way pass the correct token in some other way and skip the default behaviour of the SDK? Since we have the token needed for doing the user token exchange for PrincipalPropegation in the event metadata (which can be accessed by the eventhandler).
Any suggestions would be great!
Danny
You can conveniently propagate the thread context to new threads using the ThreadContextExecutor:
ThreadContextExecutor executor = new ThreadContextExecutor();
Callable operationWithContext = () -> executor.execute(() -> operation());
invokeAsynchronously(operationWithContext);
Check out the documentation on the topic.
Is there a way pass the correct token in some other way and skip the default behaviour of the SDK?
In case the solution with ThreadContextExecutor is not working for you, we can look for a workaround: If you are looking for a way to pass an access token inside the child thread, then use the following code sample:
import com.sap.cloud.sdk.cloudplatform.security.AuthTokenAccessor;
import com.sap.cloud.sdk.cloudplatform.security.AuthToken;
DecodedJWT jwt = JWT.decode("your-access-token");
AuthToken authToken = new AuthToken(jwt);
AuthTokenAccessor.executeWithAuthToken(authToken, () -> {
// do things..
});
Please note: Besides current auth-token, the Cloud SDK may also extract principal and tenant information from the passed JWT.

Foxx/ArangoDB: Can you create a response that adhere to JSON API specification?

I am currently writing some micro services with Foxx to be consumed by Ember.js. Ember data plays very nicely with JSON API (http://jsonapi.org) responses. So I tried to serialize the Foxx responses with the json-api-serializer (https://www.npmjs.com/package/json-api-serializer) - but with no luck. I only found the forClient method, but this only allows me to operate on the JSON representation of single objects, not the whole response. So my question: Is it possible to implement JSON API with Foxx/ArangoDB?
You can return arbitrary responses from Foxx routes, so it's entirely possible to generate JSON responses that conform to JSON API.
However there's no built-in way to do this automatically.
I don't see anything in json-api-serializer that shouldn't work in Foxx, so I'm not sure what problems you are encountering. You should be able to simply return the output object with res.json(outputFromSerializer) and set the content type with res.set('content-type', 'application/vnd.api+json').
If everything else fails you can just write your own helper functions to generate the boilerplate and metadata JSON API expects.

ServiceStack Service structure for predominantly read-only UI

I'm getting started with ServiceStack and I've got to say I'm very impressed with all it has under the bonnet and how easy it is to use!
I am developing a predominantly read-only application with it. There will likely be updates to the database 3 or 4 times a year but the rest of the time the solution will be displaying data on an electronic information board (large touch screen monitor).
The database structure is well normalised with a few foreign keyed tables and with this in mind I think it may be best to separate the read only API from the CRUD API. The CRUD API can be used to create and modify the relational data with POCO classes matching the database tables. I would then ensure the read-only API flattens the relational data into a few POCOs spanning a few db tables making the data easier to handle on the read-only UIs.
I'm just looking for ideas and advice really on whether this separation of concerns is wasted effort or if there is a better way of achieving what I need? Has anyone had similar thoughts / ideas?
Having developed a similar read only application (a gazetteer, updated quarterly/yearly) using ServiceStack we went with optimizing the API for reads, making use of the built in caching:
// For cached responses this has to be an object
public object Any(CachedRequestDto request)
{
string cacheKey = request.CacheKey;
return this.RequestContext.ToOptimizedResultUsingCache(
base.Cache, cacheKey, () =>
{
using (var service = this.ResolveService<RequestService>())
{
return service.Any(request.TranslateTo<RequestDto>()).TranslateTo<CachedResponseDto>();
}
});
}
Where CacheKey is just:
public string CacheKey
{
get
{
return UrnId.Create<CachedRequestDto>(string.Format("{0}_{1}", this.Field1, this.Field2));
}
}
We did start creating a CRUD / POCO service, but for speed went with using bulk import tools such SQL Server DTS/SSIS or console apps which suffices for now, and will revisit this later if required.
Might want to consider something like CQRS.
https://gist.github.com/kellabyte/1964094 (or Google for CQRS Martin Fowler, can only post 2 links).
Also found the following article valuable recently when starting to implement additional search type services: https://mathieu.fenniak.net/stop-designing-fragile-web-apis/

How to get x-ms-request-id from Azure table storage api call

I getting slow behavior for my azure tablestorage api calls on a windows azure app.I need to get the request id (x-ms-request-id in the response header) for a particular call. Is there a way I can get it using the storageclient api? Does the storage client api even expose this id? If not, is there any other way to get this id?
I am using the api in the following way:
public UserDataModel GetUserData(String UserId)
{
UserDataModel osudm = null;
try
{
var result = (from c in GetServiceContext().OrgUserIdTable
where (c.RowKey == UserId)
select c).FirstOrDefault();
UserDataSource osuds = new UserDataSource(this.account);
osudm = osuds.GetUserData(result.PartitionKey, result.UserName);
}
catch (Exception e)
{
}
return osudm;
}
What you're asking here is more related to WCF Data Services than it is to Windows Azure (the storage client client API uses this). Here is some example code how you can access the response headers:
var tableContext = new MyTableServiceContext(...);
DataServiceQuery<Order> query = tableContext.Orders.Where(o => o.RowKey == "1382898382") as DataServiceQuery<Order>;
IEnumerable<Order> result = query.Execute();
QueryOperationResponse response = result as QueryOperationResponse;
string requestId;
response.Headers.TryGetValue("x-ms-request-id", out requestId);
So what you'll be doing first is simply create your query and cast it to a DataServiceQuery of TType. Then you can call the Execute method on that query and cast it to a QueryOperationResponse. This class will give you access to all headers, including the x-ms-request-id.
Note that in this case you won't be able to use FirstOrDefault, since this doesn't return an IQueryable and you can't cast it to a DataServiceQuery of TType (unless there's an other way to do it using WCF Data Services).
Note: The reason why the call is so slow might be caused by your query. When you query the OrgUserIdTable table, you only filter based on the RowKey. I don't know how much data or partitions you have in that table, but if you don't use the PartitionKey this might have a significant performance impact. You have to know that, by not including the PartitionKey, you'll force a search on all partitions (possibly over multiple servers) which might be causing the call being so slow.
I suggest you take a look at the following real world guidance to get a better insight on how and why partitioning relates to performance in Windows Azure Storage: Designing a Scalable Partitioning Strategy for Windows Azure Table Storage

Resources