OOF/HAS Create/Update API
Interface Defintion | Description |
---|---|
URI | https://{host}:{port}/api/oof/v1/placement |
Operation Type | POST |
Content-Type | application/json |
Request Header
Header Name | Required? | Description |
---|---|---|
Accept | N | Determines the format of the body of the response. Valid value is “application/json” |
Authorization | Y | Supplies Basic Authentication credentials for the request. If the Authorization header is missing, then an HTTP 400 Invalid Request response is returned. If the string supplied is invalid, then an HTTP 401 Unauthorized response is returned. |
Content-Type | Y | Determines the format of the request content. Only application/json is supported. |
Content-Length | N | Number of bytes in the body of the request. Note that content length is limited to 1 MB. |
Request Body
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
requestInfo | Y | 1 | RequestInfo Object | The content of the RequestInfo object. | |
placementInfo | Y | 1 | PlacementInfo Object | The Content of the PlacementInfo object. | |
licenseInfo | N | 1 | LicenseInfo Object | The Content of the LicenseInfo object. | |
serviceInfo | Y | 1 | ServiceInfo Object | The Content of the ServiceInfo object. |
RequestInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
transactionId | Y | 1 | UUID/String | A unique ID to track an ONAP transaction. | |
requestId | Y | 1 | UUID/String | A unique ID to track multiple requests associated with a transaction. | |
callbackUrl | Y | 1 | URL | The end point of a callback service where recommendations are posted. | |
callbackHeader | N | 1 | JSON blob | The header information a client expecting in a async callback. | |
sourceId | Y | 1 | String | The unique ID of a client making an optimization call. | |
requestType | Y | 1 | String | create, update, delete | The type of a request |
numSolutions | N | 1 | Integer | Expected number of solutions. numSolution can also be specified using an optimization query policies, where the default configured value is 1. The value from a request gets higher precedence over the value defined in a policy. | |
optimizers | Y | 1..N | List of Strings | placement | A list of optimization services. |
timeout | N | 1 | Integer | A tolerance window (in secs) for expecting solutions. Default is 600 secs. |
PlacementInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
requestParameters | C | 1 | JSON BLOB | A JSON object conaining service and customer-specific data. A client or service designer is required to specify the parameters of interest for a given service and their location in the JSON blob through optimization query policies. This attribute is only required if a request contains service or customer-specific information. | |
placementDemands | Y | 1..N | List of PlacementDemand Object | The resource information for a placement service. | |
subscriberInfo | N | 1 | SubscriberInfo Object | The information of a service subscriber. |
PlacementDemand Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
resourceModuleName | Y | 1 | String | A resource name as defined in a service model. | |
serviceResourceId | Y | 1 | String | A unique resource Id with a local scope between client and OOF. | |
tenantId | N | 1 | String | A tenant Id as defined in the ordering system. | |
resourceModelInfo | Y | 1 | ModelMetaData Object | Resource model information as defined in SDC. | |
existingCandidates | N | 1..N | List of Candidates Objects | The existing placement information of a resource. | |
excludedCandidates | N | 1..N | List of Candidates Objects | Candidates that need to be excluded from solutions. | |
requiredCandidates | N | 1..N | List of Candidates Objects | Candidates that must be included in solutions. |
SubscriberInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
globalSubscriberId | Y | 1 | String | An ID of a subscriber. | |
subscriberName | Y | 1. | String | The name of a subscriber. If the name is not known, the value must be 'unknown'. | |
subscriberCommonSiteId | N | 1 | String | Id representing a subscriber location. |
ModelMetaData Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
modelInvariantId | Y | 1 | String | A model invariant Id as defined in a service model. | |
modelVersionId | Y | 1 | String | A unique model Id as defined in a service model. | |
modelName | N | 1 | String | A model name as defined in a service model. | |
modelType | N | 1 | String | A model type as defined in a service model. | |
modelVersion | N | 1 | String | A model version as defined in a service model. | |
modelCustomizationName | N | 1 | String | A model customization name as defined in a service model. |
Candidates Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
identifierType | Y | 1 | String | serviceInstanceId, vnfName, cloudRegionId, vimId | The type of a candidate. |
identifiers | Y | 1..N | List of Strings | A list of identifiers. | |
cloudOwner | C | 1 | String | The name of a cloud owner. Only required if identifierType is cloud_region_id. |
ServiceInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
serviceInstanceId | Y | 1 | String | A service instance id associated with a request. | |
modelInfo | Y | 1 | ModelMetaData Object | A list of identifiers. | |
serviceName | Y | 1 | String | The name of a service. |
LicenseInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
licenseDemands | Y | 1..N | List of LicenseDemands Object | A list of resources for license selection. |
LicenseDemands Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
resourceModuleName | Y | 1 | String | A resource name as defined in a service model. | |
serviceResourceId | Y | 1 | String | A unique resource Id with a local scope between client and OOF. | |
resourceModelInfo | Y | 1 | ModelMetaData Object | Resource model information as defined in a service model. | |
existingLicenses | N | 1 | LicenseModel Object | Existing license information assigned to a resource. |
LicenseModel Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
entitlementPoolUUID | Y | 1..N | List of Strings | Entitlement pool UUIDs associated with a resource. | |
licenseKeyGroupUUID | Y | 1..N | List of Strings | License key groups associated with a resource. |
Synchronous Response Body
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
requestId | Y | 1 | UUID/String | A unique Id for an ONAP transaction. | |
transactionId | Y | 1 | UUID/String | A unique ID to track multiple requests associated with a transaction. | |
statusMessage | N | 1 | String | Reasoning if a requestStatus is failed. | |
requestStatus | Y | 1 | String | accepted, failed | The status of a request. |
Asynchronous Response Header
Header Name | Required? | Description |
---|---|---|
Accept | N | Determines the format of the body of the response. Valid value is “application/json” |
Authorization | Y | Supplies Basic Authentication credentials for the request. If the Authorization header is missing, then an HTTP 400 Invalid Request response is returned. If the string supplied is invalid, then an HTTP 401 Unauthorized response is returned. |
Content-Type | Y | Determines the format of the request content. Only application/json is supported. |
Attribute | N | Attribute and respecrtive value that a client has sent in the callbackHeader field of a requerst. |
Content-Length | N | Number of bytes in the body of the request. Note that content length is limited to 1 MB. |
Asynchronous Response Body
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
requestId | Y | 1 | UUID/String | A unique Id for an ONAP transaction. | |
transactionId | Y | 1 | UUID/String | A unique ID to track multiple requests associated with a transaction. | |
statusMessage | N | 1 | String | Reasoning if requestStatus is failed. | |
requestStatus | Y | 1 | String | completed, failed, pending | The status of a request. |
solutions | Y | 1 | Solution Object | Solutions related to a request. |
Solution Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
placementSolutions | Y | 1..N | List of ComprehensiveSolution Object | A list of placement solutions. | |
licenseSolutions | Y | 1..N | List of LicenseSolution Object | A list of license solutions |
ComprehensiveSolution Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
- | Y | 1..N | List of PlacementSolution Object | A list of placement solutions. |
PlacementSolution Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
resourceModuleName | Y | 1 | String | The name of a resource as defined in the service model. | |
serviceResourceId | Y | 1 | String | A resource Id as defined in a service model. | |
solution | Y | 1 | Candidates Object | The placement solution | |
assignmentInfo | N | 1..N | List of AssignmentInfo object | Additional information related to a candidate. |
AssignmentInfo Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
key | Y | 1 | String | An attribute name. | |
value | Y | 1 | String | An attribute value. |
LicenseSolutions Object
Attribute | Required? | Cardinality | Content | Values | Description |
---|---|---|---|---|---|
resourceModuleName | Y | 1 | String | A resource name as defined in a service. | |
serviceResourceId | Y | 1 | String | A resource Id as defined in a service. | |
entitlementPoolUUID | Y | 1..N | List of String | A list of entitlementPoolUUIDs. | |
licenseKeyGroupUUID | Y | 1..N | List of String | A list of licenseKeyGroupUUID. | |
entitlementPoolInvariantUUID | Y | 1..N | List of String | A list of entitlementPoolInvariantUUID . | |
licenseKeyGroupInvariantUUID | Y | 1..N | List of String | A list of licenseKeyGroupInvariantUUID . |
HTTP Response Code
HTTP Code | Response Phrase | Description |
---|---|---|
201 | Created | An optimization solution is found. |
202 | Accepted | An optimization request is accepted. |
400 | Bad request | Bad request. |
401 | Unauthorized | Request body is not compliant with the API definition. |
404 | Not found | The server cannot find the requested URI. |
405 | Method not found | The requested method is not supported by a server. |
500 | Internal server error | The server encountered an internal server error or timed out. |
520 | Solver error | Requested number of solutions cannot be found. |
Request Example
Synchronous Response Example
Asynchronous Response Example
Optimization Query Policies
To enable service-agnostic API for the OOF/HAS application, the requestParameters object is modeled as JSON blob. An OOF/HAS client is expected to send service-specific and customer-specific information in a JSON format. The API allows a client to define any object structure in a JSON blob; however, the naming conventions used in the JSON blob must be the same as defined in a service model or customer order. Which information of a JSON blob is relevant for a service and where the information is located in the JSON blob should be captured through query policies. The location of an object in a JSON blob can be specified using an xpath with dot notations as shown in the following example. These optimization query policies can be configured by either a service provider or a client.
OOF/HAS API document (pdf format)
46 Comments
Manoj Nair
Few comments queries on the APIs
Ankitkumar Patel
Shankaranarayanan Puzhavakath Narayanan
Manoj, Ankit,
Our current notion of candidates captures either a cloud-region in which new VNF can be spun up, or an allotted resource, which is a slice of an existing service. That said, I think it is certainly feasible to have a "tenant" candidate, once we have a use case, requirements, and data models that require and support tenant level homing.
maopeng zhang
Few comments on the API:
RESTful API design please refer to https://wiki.onap.org/display/DW/RESTful+API+Design+Specification
Also in PlacementInfo, the "givenPlacement" also is needed so that resources can use one tenant.
Ankitkumar Patel
Thanks Maopeng for the suggestions.
I will update the definition based on your suggestions (1, 2, 4, 5, 6, 8). Can you please elaborate on comment # 3? For comment#7, are you asking for the definition of the requestParameter object?
Ankit
maopeng zhang
comment 3#: requestType of "RequestInfo Object" suggests qualifier is "O", not "M" and remove the values if not used. I guess maybe it can be used as the resource add or delete.
comment 7#: No, it is the requestParameters of "PlacementInfo Object"
Ankitkumar Patel
I updated (1) the request example by capturing placementInfo element and (2) the definition of RequestInfo object.
maopeng zhang
Comments more:
licenseDemands cardinality should be 1...N
licenseSolutions cardinality should be 1...N
should Candidates object add the tenant, zone and make it more flexible and make it as an combined conditions?
Notes1: why put the license and placement together in one API?
Notes2: what's difference between the candidates object and assignmentInfo ?
Ankitkumar Patel
Hi Maopeng,
I just updated the API definition based on your suggestions.
(3) Since the current use cases do not support homing at tenant/zone level, let's introduce generality as we find use cases in future.
(4) The assignementInfo object is extensible to capture other details like vimid, regionid, tenant, zone or zone group related to the placement solution.
(6) placementSolution is a list of list, where an outer list contains 1..N placement solutions for a request. An inner list contains a comprehensive solution (placement solution for each demand) for a request since demands are placed relative to each other. So, ComprehensiceSolution object is modeled to introduce the grouping.
Marcus Williams
In Candidates Object, can we add identifier 'vim_id' and use a list of tuples (cloud_region_id, cloud_owner)? Or can we accommodate use of vim_id in some other form in the initial request (possibly vim_id as string in place of cloud_region_id that is then decoded)?
Also, this API is accessed directly correct? I.E. Is is not using MSB.
I'm working on implementation on SO side.
Srinivasa Addepalli
Hi Marcus,
In response, I see this:
"assignmentInfo"
: [
{
"key"
:
"cloudOwner"
,
"value"
:
"amazon"
},
{
"key"
:
"cloud_region_id"
,
"value"
:
"1ac71fb8-ad43-4e16-9459-c3f372b8236d"
}
So, are we good on response side?
On request side, yes, I see this:
"requiredCandidates"
: {
"identifierType"
:
"cloud_region_id"
,
"identifiers"
: [
"TXAUS219"
] }
I guess, you are referring to this in your comment. I don't know what this is meant for, but, can we follow similar structure as in response, that is adding Cloudowner along with cloud_region_id? That way, there are all consistent.
Ankitkumar Patel?
Shankaranarayanan Puzhavakath Narayanan
Srini, Marcus,
the requiredCandidates is a mechanism that restricts the selection of a candidate for homing within the list of candidates that is provided in this block. One common use case for this block is when we need to do a partial homing, where a subset of the VNFs of the service have a predetermined location, but affects the placement of other VNFs of the service due to policy dependencies that span across these VNFs (like distance bound). While it is true that cloud_region_id is currently treated analogous to a primary key in the current version of the code, it is easy to extend this to the tuple, like Srini mentioned.
Ankitkumar Patel
Hi Srini,
cloud_region_id is sufficient enough for the required candidates since the other related information to the cloud_region_id can be fetched from A&AI. (Shankaranarayanan Puzhavakath Narayanan: please confirm). On the other hand, the generic key-value structure in the response is modeled to capture additional information related a placement solution in an extensible manner. For example, if a placement solution is a service instance, related cloud_region_id and cloud_owner information is captured in the assignmentInfo section of the response.
Ankit
Marcus Williams
Srini, yes I believe the response side has enough information. I'm concerned that the request coming from SO or request side does not have enough to uniquely identify a cloud for existing/required/excluded candidates. I.E. we should add cloud_owner to the request, something like
"requiredCandidates"
: {
"identifierType"
:
"vim_id"
,
"identifiers"
: [
"cloudowner_TXAUS219"
] }.
Then OOF can decompose and use as composite key when looking up cloud-region in AAI.
Ankitkumar Patel
Hi Marcus,
Since ID is sufficient information for existing/required/excluded candidates and the other related information to ID can be fetched from AAI, we just need a list of strings for identifiers rather than a list of tuples. Yes, we can extend the domain of identifierType by including vim_id; Do you know any use case that requires a candidate type to be vim_id?
We plan to expose the homing service through MSB, and thus, SO can discover the service through MSB API-gateway. On the other hand, OOF/HAS expects a callback url from SO where solutions can be asynchronously posted. Will SO's callback endpoints be discoverable through MSB?
Ankit
Marcus Williams
Ankit,
From what I understand, cloud_region_id alone suffers from lack of uniqueness and using it could create issues using multiple cloud if clouds have the same cloud_region_id. From AAI Schema: "Cloud regions are uniquely identified by a composite key, cloud-owner + cloud-region-id" (https://github.com/onap/aai-aai-common/blob/master/aai-schema/src/main/resources/aai_schema/aai_schema_v13.xsd#L1869) which is essentially the vim_id decomposed by separating based on "_" into cloud-owner + cloud-region-id.
It seems we should use something like vim_id or a tuple of cloud-owner + cloud-region-id in API interactions to uniquely identify clouds. See this https://wiki.onap.org/download/attachments/25429038/HowToAddNewCloudRegionAndThoughts.pdf?version=2&modificationDate=1520214136000&api=v2 - I believe Bin Yang can explain what's happening here better if needed.
Thanks for the info on OOF/HAS using MSB. We didn't have plans to include SO's callback endpoints as discoverable through MSB, but would that be helpful? In our first request to OOF/HAS, we send the callback url.
Thanks,
Marcus
Shankaranarayanan Puzhavakath Narayanan
Marcus Williams, I believe using the tuple would work fine from OOF perspective. We track the cloud_provider and cloud-region-id for each candidate when determining the placement, and it should be easy, if not already being done, to add the code that ensures the tuple is returned with the homing recommendations.
Dileep Ranganathan, Ikram Ikramullah - If we have the time, we should also consider having a vim_id attribute for the candidates, and have it as an optional attribute. We populate these candidate attributes in our data plugin, and pass it around when exploring the solution space, so it may be easy to just create a vim_id attribute and compose it as vim_id = {cloud_owner} + "_" + {location_id}
Bin Yang
Shankaranarayanan Puzhavakath Narayanan It will be great to have vim_id there to specify the cloud region. But for you information that the community also suggest to use both "cloud_owner" and "cloud_region_id" (separately , not concatenated form) to identify the cloud region. So would it be better to have them both from OOF part to accommodate both solution?
Ankitkumar Patel
Would the following structure be good enough to capture the details?
Bin Yang
@Ankitkumar Patel
could you come up with an example with 2 or 3 cloud regions from different cloud providers as "required Candidates" and we will see how it will be represented in your structure. Thanks
Ankitkumar Patel
Just updated the example. Is that what you are looking for?
Cory Boslet
if we are going to do key/value pairs, i dont like having a separate field for cloud_owner but i do understand why its needed for cloud region cases, just trying to think of a better way of doing this..
Ankitkumar Patel
I am with you, but we don't have a better alternative.
Manoj Nair
Ankit,
Can you please clarify - whether OOF has any scope during the pre-ordering phase of Service lifecycle - i.e before an actual order is placed on ONAP, is OOF is planned to support any API calls with respect to Service Qualification (feasibility check) ? I am referring here to TMF 645 Service Qualification specification . The use cases mentioned in TMF spec is closely related to what OOF offers (few examples captured below)
I believe even if TMF 645 is focused on the PreOrder phase, some of the modeling constructs can be reused. Also I think currently OOF is focused on Resource Qualification - i.e given set of constraints find out the optimum results to fulfil a resource requirement. TMF 645 seems to be Service focused. Is it worthwhile to consider some of the APIs and Model Constructs mentioned in TMF 645 . The advantage I see are the following
Shankaranarayanan Puzhavakath Narayanan
Manoj,
Thanks for bringing this up. We have indeed been thinking about the role of placement optimizations in the pre-ordering phase, but haven't really come across a pressing use case until now. One of the use cases outside of service instantiation we have been exploring is capacity planning. Service qualification seems like an interesting idea to explore - we should certainly discuss this in one of our weekly calls.
Ankitkumar Patel
Hi Manoj,
A solver can be used in either an optimization mode or feasibility checking mode. In OOF, the mode of operation can be specified by a client through policies (e.g. optimization objective or feasibility checking). As Shankaranarayanan Puzhavakath Narayanan mentioned, the R2 use case requires the homing solver to operate only in the optimization mode; however, it should be straight forward to extend the solver into the feasibility checking mode down-the-road. I am not familiar with the TMF specs. It would be great if you can educate the group in one of the meetings.
Ankit
Rob Daugherty
Cory and I approve this API on behalf of SO.
Cory Boslet
Yes, ^^
Avteet Chayal
Hi Ankit,
I found inconsistency in the naming convention in field names in request and response.I would suggest we should use camel case convention to keep it consistent across all fields.
Ankitkumar Patel
Thanks Avteet! I just updated the specs and examples with camel case only.
Marcus Williams
Hi Ankit,
There appears to be a typo. Shouldn't vmId be vimId?
Ankitkumar Patel
You caught me! I just fixed the typo.
Avteet Chayal
Hi Ankit,
In
"Optimization Query Policy Example" and "requestParameter JSON blob Example", shouldn't we have requestParameters instead of orderInfo? Also, in SO-OOF/HAS Request Example, we need to update
requestParameters
content to match with therequestParameter JSON blob Example
forcustomer details.
Ankitkumar Patel
requestParameter is a JSON blob, and so, a client can capture any information using any attribute name in any structure in a JSON format. However, what information is relevant for a given service and where the information is located in the JSON blob must be specified through query policies. The query policies must be defined by a service designer or a client.
Cory Boslet
The requestStatus and StatusMessage in the table is inconsistent with the examples provided. Can you please clarify.
Cory Boslet
What is in the table:
N
1
String
Reasoning if requestStatus is failure.
requestStatus
Y
1
String
success, failure, pending
The status of a request.
What is in the examples:
{
"transactionId"
:
"xxx-xxx-xxxx"
,
"requestId"
:
"yyy-yyy-yyyy"
,
"requestStatus"
:
"completed"
,
"statusMessage"
:
"Success!"
,
Cory Boslet
Ankitkumar Patel
Thanks Cory! I just fixed the inconsistencies that you pointed out.
Ankitkumar Patel
Hi Marcus Williams:
OOF/HAS is expecting customer location details (
"requestParameters"
: {
"customerLatitude"
: 32.89748,
"customerLongitude"
: -97.040443,
"customerName"
:
"xyz"
}
) as a part of the requestParameters in a request. Does SO have customer location information?Ankit
Marcus Williams
I'm expecting this to come from VID/Robot ect. when the service is created via userParams in the REST call. See this for more detail: https://gerrit.onap.org/r/#/c/34357/
I'll then pass that info to OOF when we make homing call to OOF.
Chittaranjan Sardar
Hi Ankitkumar,
I believe, SO will receive placement suggestions in either of the following ways -
Thanks
Ankitkumar Patel
OOF will asynchronously send the recommendations on a callback url/end point that is sent in a request.
Ankit
Marcus Williams
Agree with Ankit. SO will send a request for homing to OOF that includes a callback url. SO will then listen on that callback url for an async response that contains homing/placement info.
Chittaranjan Sardar
Hi Ankitkumar, Shankaranarayanan
In Asynchronous Response, "placementSolutions" contains Array inside another Array(immediately), see bellow highlighted -
{
"transactionId": "xxx-xxx-xxxx",
"requestId": "yyy-yyy-yyyy",
"requestStatus": "completed",
"statusMessage": "",
"solutions": {
"placementSolutions": [
[{
"resourceModuleName": "vGMuxInfra",
"serviceResourceId": "someResourceId",
"solution": {
"identifierType": "serviceInstanceId",
"identifiers": ["gjhd-098-fhd-987"]
},
....
.....
I think, it will be only one Array, else it will create problem in mapping to Object Models
Ankitkumar Patel
No, it should be list of list. The inner list contains a solution for a request and the outer list contains more than one solutions.
Cory Boslet
right, there can be multiple solutions...