Note: In order to use any of the listed new features, the URL version part must be v2.4 or higher.
To find out if plugin supports direct file access URLs a new policy, named SupportsFileAccessUrl, is introduced. This Policy has 4 properties:
To get file access key you need to query ../FileAccess/FileAccessKey and provide 2 filters:
What is more, to achieve the same result, shorten URL form can be used:
GET https://localhost/ws/v2.4/Repository/{repositoryId}/{schemaName}/{className}/{instanceId}/FileAccess.FileAccessKey?$filter=Permissions+eq+'Read'
Response:
{
"instances": [{
"instanceId": ".AzureBlobSasUrl.Read.{schemaName}.{className}.{instanceId}",
"schemaName": "FileAccess",
"className": "FileAccessKey",
"properties": {
"Url": "https://...",
"Type": "AzureBlobSasUrl",
"Permissions": "Read",
"RequiresConfirmation": false
}
},
{
"instanceId": ".Default.Read.{schemaName}.{className}.{instanceId}",
"schemaName": "FileAccess",
"className": "FileAccessKey",
"properties": {
"Url": "../{schemaName}/{className}/{instanceId}/$file?token=3AT5H174NDD13",
"Type": "Default",
"Permissions": "Read",
"RequiresConfirmation": false
}
}
]
}
If you only want one URL per instance, you can add api.singleurlperinstance=true as query parameter. This will return first available URL for each instance. It means that AzulreBlobSasUrl will be returned if it is supported and only if it is not supported - Default URL will be returned.
If URL required upload confirmation, a POST request needs to be done to https://localhost/ws/v2.4/Repositories/{repositoryId}/FileAccess/UploadConfirmation
{
"instance": {
"schemaName": "FileAccess",
"className": "UploadConfirmation",
"relationshipInstances": [{
"schemaName": "FileAccess",
"className": "UploadConfirmationForKey",
"direction": "forward",
"relatedInstance": {
"schemaName": "FileAccess",
"className": "FileAccessKey",
"instanceId": "{previouslyRetrievedFileAccessKeyInstanceId}"
}
}]
}
}
As a shorthand POST URL introduced in v2.4, you can also POST to this URL without any payload:
If you want to update instance at the same time when confirming file upload, you can do it by specifying it as additional related item to UploadConfirmation instance. Instance should be the same as {previouslyRetrievedFileAccessKeyInstanceId}.
Example:
{
"instance": {
"schemaName": "FileAccess",
"className": "UploadConfirmation",
"relationshipInstances": [{
"schemaName": "FileAccess",
"className": "UploadConfirmationForKey",
"direction": "forward",
"relatedInstance": {
"schemaName": "FileAccess",
"className": "FileAccessKey",
"instanceId": "{previouslyRetrievedFileAccessKeyInstanceId}"
},
},
{
"schemaName": "FileAccess",
"className": "UploadConfirmationInstance",
"direction": "forward",
"relatedInstance": {
"schemaName": "{schemaName}",
"className": "{className}",
"instanceId": "{instanceId}",
"properties": {
{Properties to update while confirming}
}
}
}]
}
}
File access API was added to current file GET/PUT requests as well.
When you normally get a file using GET https://localhost/ws/v2.4/repositories/{repositoryId}/{schema}/{class}/{instanceId}/$file, you can add additional header Mas-Allow-Redirect: true.
Adding this header will inform WSG that if it can generate direct file access URL for the file - it should redirect to it.
When you normally put a file using PUT https://localhost/ws/v2.4/repositories/{repositoryId}/{schema}/{class}/{instanceId}/$file, you can add additional header Mas-Allow-Redirect: true.
Adding this header will inform WSG that if it can generate direct file access URL for the file - it should redirect to it.
Note! After you get redirected, it is up to you to work with its API. Currently, only AzureSasBlobUrl type is supported. So you will get redirected to either GET or PUT to Azure blob.
Starting with version 2.4, the $orderby keyword can be used to order by related class properties. For example:
Starting with version 2.4, it is possible to query connection parameters formats for all or specific plugins. For example:
Count query returns the number of instances for each specified class. Query example:
GET https://localhost/ws/v2.4/Repositories/{repository}/{schema}/{classes}/$count?$filter={filter}
{
"instances": [{
"instanceId": "{instanceId}",
"schemaName": "{schema}",
"className": "InstanceCount",
"properties": {
"ECSchemaName": "{schema}",
"ECClassName": "File",
"Count": 599
},
"eTag": "U99S1g99huTQSE8u2999999999s="
}]
}
Note for developers:
'InstanceCountQuery' is passed to plugin. It contains the inner query in extended data. The inner query is the same executed query but without count part. Some plugins may require it because this query contains more information.
Inner query is retrieved from EC Framework 'CountQueryAccessor' class.
It is possible to hide specific repositories from users by modifying <hiddenRepositories> attribute in "ecom.config" file. Moreover, there is an option to deny access if needed by specifying denyAccess="true" parameter (false by default). Location property value can be found by querying for repositories.
If you need only to hide repository:
<HiddenRepositories>
<Repository pluginId="Bentley.PW" location="host.domain.com:datasource" />
</HiddenRepositories>
If you need to hide and deny access to repository:
<HiddenRepositories>
<Repository pluginId="Bentley.PW" location="host.domain.com:datasource" denyAccess="true"/>
</HiddenRepositories>
It is now possible to POST and link a new instance to the existing instance in the same request. A relationship will automatically be created between them. The request otherwise is identical to the conventional POST instance request.
Each request is assigned a unique request ID that can be found in a request's Mas-Request-Id header. In a log file, the request ID is saved as ActivityID and can be used to sort log messages and isolate those connected to a specific request.
Instance data JSON now supports references. It is possible to use $id property when serializing an object for the first time, and $ref property in all other places where the same object must be serialized in the same JSON. If a request contains both $id and $ref properties, the response will preserve the same object references. For example:
{
"instances": [{
"$id" : "1",
"className": "{class}",
"schemaName": "{schema}",
"properties": {
"Name": "CreateDoc1236df6905k119.txt",
"Code": "Code0060"
},
"relationshipInstances": [{
"className": "FolderDocument",
"schemaName": "{schema}",
"direction": "backward",
"relatedInstance": {
"$id" : "2",
"instanceId": "186",
"className": "Folder",
"schemaName": "{schema}"
}
}]
},{
"$id" : "3",
"className": "{class}",
"schemaName": "{schema}",
"properties": {
"Name": "CreateDoc12362gf1691k58.txt",
"Code": "Code0061"
},
"relationshipInstances": [{
"className": "FolderDocument",
"schemaName": "{schema}",
"direction": "backward",
"relatedInstance": {
"$ref" : "2"
}
}]
}]
}
To overcome URL length limitation, Bentley Web Services Gateway Web API supports query execution using a POST request. The supported format is: POST https://localhost/ws/v2.4/Repositories/{repositoryId}/{schema}/{classes}/$query with string as a request body. For example:
GET https://localhost/ws/v2.4/Repositories/{repositoryId}/eb/Document!poly?$filter=Name+eq+'test'
can be replaced with the following POST request:
POST https://localhost/ws/v2.4/Repositories/{RepositoryId}/eb/Document!poly/$query
Content-Type: application/json
Authorization: Basic YWRtaW46YWRtaW4 =
Host: localhost
Content-Length: 22
$filter=Name+eq+'test'
Request options can be used to control how a request is executed and how a response is constructed in the server. Support for a specific option can be the subject of availability for each plugin. Request options can be specified in the JSON body. For example:
{
"instance": {
"instanceId": "142",
"schemaName": "{schema}",
"className": "{class}",
"properties": {
"Code": "DOC1-000058"
},
"relationshipInstances": [{
"instanceId": "120",
"schemaName": "{schema}",
"className": "Global_Relationship_DOCDOC2",
"direction": "forward",
"properties": {},
"relatedInstance": {
"changeState": "modified",
"instanceId": "143",
"schemaName": "{schema}",
"className": "{class}",
"properties": {
"Code": "DOC1-000058"
},
"relationshipInstances": [{
"instanceId": "106",
"schemaName": "{schema}",
"className": "Global_Relationship_DOCDOC2",
"direction": "forward",
"properties": {},
"relatedInstance": {
"changeState": "modified",
"instanceId": "144",
"schemaName": "{schema}",
"className": "{class}",
"properties": {
"Code": "DOC1-000058"
}
}
}]
}
}]
},
"requestOptions": {
"FailureStrategy": "Continue"
}
}
Currently available request options:
FailureStrategy: Stop causes the request to execute until the first error. If an error occurs, a standard error JSON is returned. This is default behavior.
FailureStrategy: Continue causes the server to execute all changeset requests, even if some requests fail. "Change" property is returned for all instances indicating if it was changed. Error property is returned indicating which instances failed to execute. Response will return success, even if some operations fail. Sample response:
{
"changedInstance": {
"change": "Unchanged",
"instanceAfterChange": {
"instanceId": "142",
"schemaName": "{schema}",
"className": "{class}",
"change": "Unchanged",
"error": {
"errorMessage": "There is already another Document with this Prefix, Middle and Revision.",
"httpStatusCode": 500
},
"properties": {
"Code": "DOC1-000058"
},
"relationshipInstances": [{
"instanceId": "120",
"schemaName": "{schema}",
"className": "Global_Relationship_DOCDOC2",
"change": "Unchanged",
"direction": "forward",
"properties": {},
"relatedInstance": {
"instanceId": "143",
"schemaName": "{schema}",
"className": "{class}",
"change": "Unchanged",
"error": {
"errorMessage": "There is already another Document with this Prefix, Middle and Revision.",
"httpStatusCode": 500
},
"properties": {
"Code": "DOC1-000058"
},
"relationshipInstances": [{
"instanceId": "106",
"schemaName": "{schema}",
"className": "Global_Relationship_DOCDOC2",
"change": "Unchanged",
"direction": "forward",
"properties": {},
"relatedInstance": {
"instanceId": "144",
"schemaName": "{schema}",
"className": "{class}",
"change": "Unchanged",
"error": {
"errorMessage": "There is already another Document with this Prefix, Middle and Revision.",
"httpStatusCode": 500
},
"properties": {
"Code": "DOC1-000058"
}
}
}]
}
}]
}
}
}
ResponseContent:FullInstance results full instance information to be returned in the response (this is default behavior).
ResponseContent:Empty causes the response body to be empty - only the HTTP status is returned.
ResponseContent:InstanceId results only class information and instance IDs to be returned. All properties are removed from the response.
RefreshInstances:false is a default option. Additional steps are not executed after the request.
RefreshInstances:true results that newly created or modified instances need to be refreshed before serializing to JSON. If a plugin does not support a refresh operation, Bentley Web Services Gateway will automatically execute additional requests to refresh instances. An additional property ""Refreshed"" is returned for all instances indicating if the refresh operation has succeeded.
"requestOptions": {
"CustomOptions": {
"CustomOption1": "CustomValue1"
}
}
Starting with API 2.4, the Bearer authorization header was replaced with a Token header. Header format has not changed and must be a base64-encoded SAML token. Bearer header will still be accepted for backward compatibility, but will not be returned as available.
Usage example:
Copyright © 2017 Bentley Systems, Incorporated. All rights reserved.