how to use odata services to create model dynamically from manifest.json - odata

I am very new to UI5, I am working on an application which requires me to create models based on the request made from the browser (client).
If I consume all the odata services beforehand & use them according to the request made, it will become too heavy unnecessarily.
is there any way, this can be done dynamically?

I think your question title and the question content might be contradictory so I am placing my suggestions separately.
how to use odata services to create model dynamically from manifest.json
In your manifest.json file, locate the "sap.app" section/property and then add a datasource as follows:
"dataSources": { //used data sources -> ui5-related information stored in sap.ui5 namespace (unique inside the app)
"modelalias": { //key is alias which is used below in e.g. sap.ui5 ...
"uri": "/sap/opu/odata/snce/PO_S_SRV;v=2/" , //mandatory; version is part of uri, e.g. ";v=2", default is 1
"type": "OData" , //OData (default)|ODataAnnotation|INA|XML|JSON
"settings": { //data-source-type-specific attributes (key, value pairs)
"odataVersion": "2.0" , //possible values: 2.0 (default), 4.0
"annotations": [ "equipmentanno" ], //filled e.g. for Smart Template
"localUri": "model/metadata.xml" //relative url to local metadata
"maxAge": 360 //time in seconds
}
}
To instantiate this model with the alias "mymodel", you can add an entry into the manifest.json under "sap.ui5" as follows:
"models": {
...
"mymodel": { //empty string "" is the default model
"preload": true; //indicator that the model will be created immediately after the manifest is loaded by component factory and before the component instance is created
"dataSource": "modelalias", //reference of dataSource under sap.app - only enhance it with more settings for UI5 if needed
"settings": {
}
}
},
Now the manifest file will instantiate "mymodel" based on your odata uri in "datasources" and then set the model onto your Component.js. So when your application starts, you can access the model in any controller using:
this.getOwnerComponent().getModel("mymodel")
If I consume all the odata services beforehand & use them according to
the request made, it will become too heavy unnecessarily. is there any
way, this can be done dynamically?
Your assumption is that creating a model will slow the app startup. This may not always be true since:
The model creation is very quick
Reading data is what takes time and model instantiation
ODataModels work asyncronously be default so calling .read or .write are operations that can be managed asynchronously
Special case: If you wish to pre-fetch all your data in advance (at startup) I would advise that you ensure that you utilize filters like $select, $top and $skip on your Gateway service to implement growing list like behavior.
Hope that helps you.
More information on manifest.json: Link
Growing List: Link
ODataModel Examples: Link

Related

Query string with OData linked service in Azure Data Factory

Setting up a OData linked service on public OData like at:
https://www.odata.org/odata-services/
works fine in the Azure Data Factory. Hard coding a url in the OData linked service to:
https://services.odata.org/TripPinRESTierService
from an associated data set shows the entities: People, Airlines, Airports. Previewing is helpful when setting up linked services and data sources. Would be great if that was doable with Azure Search OData endpoints.
The Azure Search requires that the api-version exist in the query string. A query string can not be added until either a Copy or LookUp activity (see documentation). Previewing in the LookUp seems not to take with it the query and the preview fails with:
Invalid or missing api-version query string parameter
Debug doesn't show the url or header with the api-key from linked service nore the path from data source. But the output does show the query (with the api-version):
{
"source": {
"type": "ODataSource",
"query": "api-version=2021-04-30-Preview",
"httpRequestTimeout": "00:05:00"
},
"dataset": {
"referenceName": "AzureODataSearch",
"type": "DatasetReference",
"parameters": {}
}
}
Anybody?

Is it possible to pass AWS EventBridge rule event variables to the target Invocation HTTP Parameters?

I am pretty sure I miss something simple but I don't seem to fins any resource on my issue and I am a novice on AWS.
The problem is as follows: I have a scenario where I would like to trigger a REST POST API when files are uploaded to an S3 bucket. This POST API uses OAuth 2.0 and requires the file name in the body.
I created a rule that successfully triggers on upload and the API works well if I put a static filename as Invocation Http Parameter. But I would like this value to be dynamic, based on the file that triggers the event.
I have tried using the jQuery snippet $.detail.object.key but, as much as it works for adding a Query Parameter from the rule, it doesn't seem to work if used in the Invocation Http Parameters settings in the API connection.
The event pattern is as follows:
{
"source": ["aws.s3"],
"detail-type": ["Object Created"],
"detail": {
"bucket": {
"name": ["jna-test-bucket"]
},
"object": {
"key": [{
"prefix": "testFileForAPI"
}]
}
}
}

Create a documentSet using graph API - configuration

I implemented with Graph API several calls to create a document set.
I followed the answer posted here concerning the possibility of creating a DocumentSet in SharePoint here : Is it possible to create a project documentset using graph API?
For this i followed those steps :
1. Getting the library driveId :
`GET https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listId}?$expand=drive`
2. Creating the folder:
POST https://graph.microsoft.com/v1.0/drives/${driveId}/root/children
I have to pass an object:
{
"name": ${nameOfTheFolder},
"folder": {},
}
3. Getting the Sharepoint itemId:
4. Updating the document library:
`PATCH https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listId}/items/${sharepointIds.listItemId}`
and passing a body:
{
"contentType": {
"id": "content-type-id-of-the-document-set"
},
"fields": {
//whatever fields you want to set
}
}
I have questions concerning the folder creation and the updating:
What is expected in the folder object ?
{
"name": ${nameOfTheFolder},
"folder": {},
}
Concerning the path step:
{
"contentType": {
"id": "content-type-id-of-the-document-set"
},
"fields": {
//whatever fields you want to set
}
}
I have several questions :
Let's consider i have a document type called invoices. Which id is expected for document type id ?
finally how do i pass the fields ? let's say i want to pass 3 fields : invoiceId, claimId, clientId.
Graph API is great but some more information would be helpful. thanks !
I have questions concerning the folder creation and the updating: What is expected in the folder object ?
The folder object (sent as {}) is there to tell graph API that you are creating a folder and not a file. It is a property of the drive item
Let's consider i have a document type called invoices. Which id is expected for document type id ?
This is the id contentType subfield of the list item you are patching
ally how do i pass the fields ? let's say i want to pass 3 fields : invoiceId, claimId, clientId.
You just pass them with repective values like below. See Update listItem
{
"invoiceId": "value",
"claimId": "value"
...
}
One point I didn't express correctly was to know what id is expected here :
{
"contentType": {
"id": "content-type-id-of-the-document-set"
},
"fields": {
//whatever fields you want to set
}
}
I retrieved the different content types of my site by calling this kind of URL and check if the content type exists.
https://graph.microsoft.com/v1.0/sites/${siteId}/lists/${listId}/contentTypes
From the result i retrieve in a Value object the id.
The id looks like this :
0x0120D5200082903AB771604546844DB2AC483D905B00E58445A7D..........
In modern SharePoint, you can also get the Content Type ID from the UI by browsing to SharePoint Site > Site Settings > Site content types > <ContentTypeName> > Content Type ID.
Content Type ID
Not sure if this is easier than via graph, but it's another option at least.

Documenting error codes definition in Swagger API contract

Imagine you are working under following circumstances:
You have REST API modules with API documentation generated into swagger-ui.html
Possible HTTP status codes for endpoints are documented well via io.swagger.annotations.* on controller method level for each endpoint.
In case of some error state (4XX or 5XX) application replies with ErrorResponseDTO with structure like
"ErrorResponseDTO": {
"type": "object",
"properties": {
"errorCode": {
"type": "integer",
"format": "int32"
},
"message": {
"type": "string"
}
}
}
Application have tens of errorCodes (within range like 1 - XX and please consider them as a legacy definiton without an easy way to change them).
List of errorCodes is relevant for the whole application so you prefer to keep their definiton list/table in overall API documentation rather then maintaining errorCodes definiton for each API endpoint separately.
Now you are looking for an effective way how to document these application error codes into API contract.
The approach of including a list of errorCodes with codes description into generated swagger-ui.html seems like a better way to keep API documentation up to date instead of having static and handwritten codes definition table attached in Markdown format in some Readme file.
Would you please have any recommendation how to document various codes which your applications produce?
Do you follow some specific good practice in this topic?
Thank you in advance.
Meanwhile within a small internal dev team and with frequent API extensions there can be used generated swagger-ui with included error codes:
#Bean
public Docket swaggerSettings() {
ApiSelectorBuilder builder = new Docket(DocumentationType.SWAGGER_2)
.apiInfo(
new ApiInfoBuilder()
.title("Response errorCodes table")
.description(RestResponse.generateErrorsDocumentation().toString())
.build()
)
...
.select();
return builder.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
.paths(PathSelectors.any())
.build()
.useDefaultResponseMessages(false);
}

Retrieve parameter from a Jenkins REST query

The following REST query will return parameters of the last successful build of a job:
https://localhost/job/test1/lastSuccessfulBuild/api/json
I'd be interested to retrieve one of the parameters of this build, the BUILD_VERSION:
{
"_class": "org.jenkinsci.plugins.workflow.job.WorkflowRun",
"actions": [
{
"_class": "hudson.model.CauseAction",
"causes": [
{
"_class": "hudson.model.Cause$UpstreamCause",
"shortDescription": "Started by upstream project \"continuous-testing-pipeline-for-nightly\" build number 114",
"upstreamBuild": 114,
"upstreamProject": "continuous-testing-pipeline-for-nightly",
"upstreamUrl": "job/continuous-testing-pipeline-for-nightly/"
}
]
},
{ },
{
"_class": "hudson.model.ParametersAction",
"parameters": [
{
"_class": "hudson.model.StringParameterValue",
"name": "BUILD_VERSION",
"value": "1.1.15"
Is there a way to retrieve the BUILD_VERSION (1.1.15) directly using the REST Api or do I have to parse manually the json string ?
Thanks
Yeah you can get the value,But it will only work for XML API :(
The JSON API will return a simplified json object using Tree :)
So Jenkins provides you with api (XML,JSON,PYTHON) from which you can read the Jenkins related data of any project. Documentation in detail is provide in https://localhost/job/test1/lastSuccessfulBuild/api
In that it clearly states that
XML API - Use XPath to control the fragment you want.For example, ../api/xml?xpath=//[0]
JSON API - Use tree
Python API - Use st.literal_eval(urllib.urlopen("...").read())
All the above can be used to get a specific fragment/piece from the entire messy data that you get from the API.
In your case, we will use tree for obvious reasons :)
Syntax : tree=keyname[field1,field2,subkeyname[subfield1]]
In order to retrieve BUILD_VERSION i.e. value
//jenkins/job/myjob/../api/json?tree=lastSuccessfulBuild[parameters[value]]
The above should get you what you want, but a bit of trail and error is required :)
You can also refer here for a better understanding of how to use Tree in JSON API
https://www.cloudbees.com/blog/taming-jenkins-json-api-depth-and-tree
Hope it helps :)
Short answer: No.
Easiest way to programmatically access any attribute exposed via the JSON API is to take the JSON from one of Jenkins supported JSON APIs (in your case: https://localhost/job/<jobname>/lastSuccessfulBuild/api/json)
Copy the resultant JSON into http://json2csharp.com
Generate the corresponding C# code. Don't forget to create a meaningful name for top level class.
Call RestAPI programmatically from C# using RestSharp.
Deserialise the json to the C# class you defined in 2 above.
Wammo, you have access to the entire object tree and all its values.
I used this approach to write an MVC5 ASP.NET site I called "BuildDashboard" to provide all the information a development team could want and answered every question they had.
Here is an example with a public jenkins instance and one of its builds in order to get "candidate_revision" parameter for "lastSuccessfulBuild" build:
https://jenkins.qa.ubuntu.com/view/All/job/account-plugins-vivid-i386-ci/lastSuccessfulBuild/parameters/
https://jenkins.qa.ubuntu.com/view/All/job/account-plugins-vivid-i386-ci/lastSuccessfulBuild/api/xml?xpath=/freeStyleBuild/action/parameter[name=%22candidate_revision%22]/value

Resources